Developers

Website-API#

Lesen und schreiben Sie den Inhalt einer NAMES LEGAL-Website über HTTPS: Dienstleistungen, Projekte, Blogbeiträge, Teammitglieder, Veranstaltungen, Stellenangebote, FAQ und mehr. Die API ist Teil des Add-ons API-Zugang der Website.

Schnellstart#

  1. Aktivieren Sie in der Konsole der Website unter Add-ons & Abonnement das Add-on API-Zugang.
  2. Module → API: Erstellen Sie einen Schlüssel. Kopieren Sie ihn jetzt — er wird nur einmal angezeigt.
  3. Rufen Sie die API auf:
KEY="nlk_3fa9c2d1_Jx0..."
curl -H "Authorization: Api-Key $KEY" "https://ecolehorizon.names.legal/api/v1/team/?lang=fr"
{
  "count": 12,
  "next": "https://ecolehorizon.names.legal/api/v1/team/?lang=fr&page=2",
  "previous": null,
  "results": [
    {"id": 4, "first_name": "Awa", "last_name": "Diop", "position": "Mathematics teacher",
     "profile_image": "https://ecolehorizon.names.legal/media/demo/team/awa.jpg",
     "updated_at": "2026-09-20T08:12:44+02:00"}
  ]
}

Basis-URL#

https://<site>/api/v1/

<site> ist die eigene Adresse der Website (ecolehorizon.names.legal oder ihre eigene Domain). Es gibt kein Sprachpräfix im Pfad. v1 ist die einzige Version; eine grundlegende Änderung würde als v2 daneben eingeführt.

Die Root-URL listet jede Sammlung auf. Eine interaktive Referenz (Swagger) und das OpenAPI-Schema sind auf jeder Website verfügbar:

URL Zugriff
Interaktive Referenz /api/v1/docs/ API-Schlüssel (beliebiger Geltungsbereich) oder ein Konsolen-Konto
OpenAPI-3-Schema /api/v1/schema/ API-Schlüssel (beliebiger Geltungsbereich) oder ein Konsolen-Konto

Authentifizierung#

  1. Der Website-Inhaber aktiviert das Add-on API-Zugang.
  2. In der Konsole, unter Module → API, erstellt er einen Schlüssel und wählt dessen Geltungsbereich. Der vollständige Schlüssel wird einmal angezeigt; gespeichert werden nur ein Präfix und ein Hash.
  3. Senden Sie den Schlüssel mit jeder Anfrage.
GET /api/v1/services/ HTTP/1.1
Host: ecolehorizon.names.legal
Authorization: Api-Key nlk_3fa9c2d1_Jx0...

Authorization: Bearer <key> und X-Api-Key: <key> werden ebenfalls akzeptiert. Schlüssel sehen aus wie nlk_<8 hexadezimale Zeichen>_<secret>.

Geltungsbereiche#

Geltungsbereich Erlaubt
read (Standard) GET auf jeder Sammlung
write GET, POST, PUT, PATCH

Der Geltungsbereich gilt für den gesamten Schlüssel; es gibt keinen Geltungsbereich pro Sammlung. Ein Schlüssel kann jederzeit über die Konsole widerrufen werden.

Fehler, die Ihnen begegnen können#

Status Bedeutung
401 Fehlender, unbekannter oder widerrufener Schlüssel: {"detail": "Invalid API key."}
403 Das Add-on ist nicht aktiv, oder ein read-Schlüssel hat versucht zu schreiben
404 /docs/ und /schema/, wenn das Add-on nicht aktiv ist
405 DELETE — das Löschen erfolgt ausschließlich über die Konsole
429 Ratenlimit überschritten
400 Validierungsfehler: {"field": ["message"]}

Sprache#

Übersetzte Felder werden jeweils in einer Sprache zurückgegeben. Wählen Sie sie mit ?lang=:

curl -H "Authorization: Api-Key $KEY" "https://ecolehorizon.names.legal/api/v1/services/?lang=fr"

Die Sprache muss eine der von der Website veröffentlichten Sprachen sein; andernfalls lautet die Antwort 400. Ohne lang wird die Standardsprache der Website verwendet. Die Antwort enthält einen Content-Language-Header.

Paginierung, Filter und Sortierung#

Listen werden nach Seitenzahl paginiert:

{
  "count": 42,
  "next": "https://ecolehorizon.names.legal/api/v1/team/?page=2",
  "previous": null,
  "results": [ ... ]
}
Parameter Wirkung
page, page_size Seitenzahl und -größe (Standard 25, Maximum 100)
search Volltextsuche auf den wichtigsten Textfeldern der Sammlung
ordering Sortierfeld, - für absteigend: ?ordering=-updated_at
Feldfilter Exakte Übereinstimmung, zum Beispiel ?category__slug=bachelor&is_featured=true
since Nur Einträge, die seit einem Datum geändert wurden: ?since=2026-09-01T00:00:00Z

since macht die inkrementelle Synchronisierung günstig: Speichern Sie den Zeitpunkt Ihres letzten Aufrufs und geben Sie ihn beim nächsten Mal an.

Ratenlimits#

  • 120 Anfragen pro Minute und API-Schlüssel (jeder Schlüssel hat seinen eigenen Zähler).
  • Konsolen-Sitzungen: 120 pro Minute. Anonyme Aufrufe: 30 pro Minute.

Bei Überschreitung des Limits antwortet die API mit 429; warten Sie und versuchen Sie es erneut.

Sammlungen#

Pfad Methoden Hinweise
services/ GET, POST, PUT, PATCH Kategorie über category_slug (optional)
projects/ GET, POST, PUT, PATCH category_slug erforderlich
blog/ GET, POST, PUT, PATCH Nur veröffentlichte Beiträge; category_slug erforderlich
team/ GET, POST, PUT, PATCH Nur aktive Mitglieder
testimonials/ GET, POST, PUT, PATCH Nur echte Erfahrungsberichte
publications/ GET, POST, PUT, PATCH category_slug optional
resources/ GET, POST, PUT, PATCH Die Datei selbst wird in der Konsole verwaltet
events/ GET, POST, PUT, PATCH Daten in ISO 8601
jobs/ GET, POST, PUT, PATCH Nur aktive Stellenausschreibungen; category_slug erforderlich
faq/ GET, POST, PUT, PATCH category_slug optional
bookable-items/ GET Erfordert das Add-on Terminplanung
bookings/ POST Eine Buchung erstellen; erfordert einen write-Schlüssel

Jeder Eintrag ist unter <collection>/<id>/ erreichbar. Die Felder jeder Sammlung sind in der Referenz weiter unten aufgeführt.

Schreiben#

  • POST erstellt, PUT ersetzt, PATCH aktualisiert einzelne Felder.
  • Kategorien werden als Objekt {"id", "name", "slug"} gelesen und mit category_slug geschrieben. Ein unbekannter Slug wird abgelehnt.
  • Bilder und Dateien sind in der API schreibgeschützt: Laden Sie sie in der Konsole hoch, oder lassen Sie den Datenkonnektor sie von einer URL herunterladen.
  • In Rich-Text-Feldern gesendetes HTML wird bereinigt: Skripte und Event-Handler werden entfernt.
curl -X POST "https://ecolehorizon.names.legal/api/v1/faq/?lang=fr" \
  -H "Authorization: Api-Key $KEY" -H "Content-Type: application/json" \
  -d '{"question": "Quand ont lieu les inscriptions ?", "answer": "<p>Du 1er au 30 juin.</p>"}'

Einen Termin buchen#

curl -X POST "https://ecolehorizon.names.legal/api/v1/bookings/" \
  -H "Authorization: Api-Key $KEY" -H "Content-Type: application/json" \
  -d '{"item": 3, "customer_name": "Awa Diop", "customer_email": "awa@example.com",
       "date": "2026-10-02", "time": "14:30"}'

time gilt in der Zeitzone der Website. Ein Termin, der nicht mehr frei ist, wird mit 400 abgelehnt. Neue Buchungen beginnen als pending.

Rezepte#

Eine Sammlung inkrementell spiegeln#

Lesen Sie einmal alles, danach nur noch die Änderungen. Speichern Sie den Zeitpunkt Ihres letzten Laufs und übergeben Sie ihn als since.

Python

import time
import requests

BASE = "https://ecolehorizon.names.legal/api/v1/"
HEADERS = {"Authorization": "Api-Key nlk_3fa9c2d1_Jx0..."}

def fetch_all(collection, since=None, lang="fr"):
    url = f"{BASE}{collection}/"
    params = {"lang": lang, "page_size": 100, "ordering": "updated_at"}
    if since:
        params["since"] = since
    while url:
        response = requests.get(url, headers=HEADERS, params=params, timeout=15)
        if response.status_code == 429:
            time.sleep(int(response.headers.get("Retry-After", "5")))
            continue
        response.raise_for_status()
        data = response.json()
        yield from data["results"]
        url, params = data["next"], None   # "next" already carries the parameters

for member in fetch_all("team", since="2026-09-01T00:00:00Z"):
    print(member["id"], member["first_name"], member["last_name"])

JavaScript (Node.js 18+)

const BASE = "https://ecolehorizon.names.legal/api/v1/";
const HEADERS = { Authorization: "Api-Key nlk_3fa9c2d1_Jx0..." };

async function* fetchAll(collection, since, lang = "fr") {
  const first = new URL(`${BASE}${collection}/`);
  first.search = new URLSearchParams({ lang, page_size: "100", ordering: "updated_at",
                                       ...(since ? { since } : {}) });
  let url = first.toString();
  while (url) {
    const response = await fetch(url, { headers: HEADERS });
    if (response.status === 429) {
      const wait = Number(response.headers.get("Retry-After") || 5);
      await new Promise((resolve) => setTimeout(resolve, wait * 1000));
      continue;
    }
    if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
    const data = await response.json();
    yield* data.results;
    url = data.next;
  }
}

for await (const post of fetchAll("blog", "2026-09-01T00:00:00Z")) {
  console.log(post.id, post.title);
}

Einen Eintrag erstellen oder aktualisieren#

PHP

<?php
$base = 'https://ecolehorizon.names.legal/api/v1/';
$headers = ['Authorization: Api-Key nlk_3fa9c2d1_Jx0...', 'Content-Type: application/json'];

function call($method, $url, $headers, $body = null) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => $headers,
                            CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15]);
    if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    $answer = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);
    return [$status, json_decode($answer, true)];
}

// Create an event (in French)
[$status, $event] = call('POST', $base . 'events/?lang=fr', $headers, [
    'title' => 'Journée portes ouvertes',
    'slug' => 'journee-portes-ouvertes-2026',
    'description' => '<p>Visite du campus et rencontre avec les enseignants.</p>',
    'start_date' => '2026-11-14T09:00:00+01:00',
    'end_date' => '2026-11-14T16:00:00+01:00',
    'location' => 'Campus de Genève',
]);

// Change only the location later
call('PATCH', $base . "events/{$event['id']}/?lang=fr", $headers, ['location' => 'Aula']);

lang bestimmt, in welcher Sprache ein übersetztes Feld geschrieben wird: senden Sie denselben Eintrag erneut mit ?lang=en, um die englische Version hinzuzufügen.

Fehler und Limits in der Praxis#

Situation Was zu tun ist
429 Too Many Requests Warten Sie die im Retry-After-Header angegebene Anzahl Sekunden und versuchen Sie es erneut.
400 beim Schreiben Lesen Sie den Antworttext: Jedes Feld listet seine Probleme auf, {"category_slug": ["Object with slug=x does not exist."]}.
403 bei einer write-Anfrage Der Schlüssel ist read: erstellen Sie einen read and write-Schlüssel.
401 Der Schlüssel wurde widerrufen oder falsch eingegeben.
Netzwerkfehler oder 5xx Versuchen Sie es mit wachsender Verzögerung erneut (1 s, 2 s, 4 s…). Lesevorgänge können gefahrlos wiederholt werden; prüfen Sie bei einem POST zuerst, ob der Eintrag nicht bereits erstellt wurde.

Referenz nach Sammlung#

Aus dem Code der API generiert: Felder, Zugriffsrechte und Abfrageparameter entsprechen immer der laufenden Plattform. Übersetzte Felder werden in der mit lang gewählten Sprache gelesen und geschrieben.

/api/v1/services/

GETPOSTPUTPATCH

  • Filter slug category__slug is_featured
  • search title description
  • ordering order title updated_at (Standard order)
FeldFeldtypZugriff
id integer nur lesen
slug string ≤ 200 lesen und schreiben
title string ≤ 100 lesen und schreiben Pflicht beim Anlegen
description string lesen und schreiben Pflicht beim Anlegen
icon string ≤ 50 lesen und schreiben Pflicht beim Anlegen
color string ≤ 25 lesen und schreiben
category object nur lesen
category_slug slug nur schreiben
is_featured boolean lesen und schreiben
order integer lesen und schreiben
seo_title string ≤ 70 lesen und schreiben
seo_description string ≤ 160 lesen und schreiben
og_image id nur lesen
updated_at datetime nur lesen

/api/v1/projects/

GETPOSTPUTPATCH

  • Filter slug category__slug status is_featured
  • search title description client technologies
  • ordering order title project_date updated_at (Standard order)
FeldFeldtypZugriff
id integer nur lesen
slug string ≤ 50 lesen und schreiben Pflicht beim Anlegen
title string ≤ 150 lesen und schreiben Pflicht beim Anlegen
description string lesen und schreiben Pflicht beim Anlegen
detailed_description string lesen und schreiben
category object nur lesen
category_slug slug nur schreiben Pflicht beim Anlegen
client string ≤ 100 lesen und schreiben
status choice
completed, in_progress, on_hold, planning
lesen und schreiben
project_date string ≤ 20 lesen und schreiben
duration string ≤ 50 lesen und schreiben
team_size string ≤ 50 lesen und schreiben
technologies string ≤ 200 lesen und schreiben
tags string ≤ 200 lesen und schreiben
image file (URL) nur lesen
demo_url url ≤ 200 lesen und schreiben
project_url url ≤ 200 lesen und schreiben
github_url url ≤ 200 lesen und schreiben
is_featured boolean lesen und schreiben
order integer lesen und schreiben
seo_title string ≤ 70 lesen und schreiben
seo_description string ≤ 160 lesen und schreiben
og_image id nur lesen
created_at datetime nur lesen
updated_at datetime nur lesen

/api/v1/blog/

GETPOSTPUTPATCH

  • Filter slug category__slug status tags__slug
  • search title excerpt content
  • ordering published_date title updated_at (Standard -published_date)
FeldFeldtypZugriff
id integer nur lesen
slug string ≤ 200 lesen und schreiben Pflicht beim Anlegen
title string ≤ 200 lesen und schreiben Pflicht beim Anlegen
excerpt string ≤ 500 lesen und schreiben Pflicht beim Anlegen
content string lesen und schreiben Pflicht beim Anlegen
category object nur lesen
category_slug slug nur schreiben Pflicht beim Anlegen
tags list of slug nur lesen
featured_image file (URL) nur lesen
published_date datetime lesen und schreiben
read_time integer lesen und schreiben
status choice
draft, published, featured
lesen und schreiben
order integer lesen und schreiben
seo_title string ≤ 70 lesen und schreiben
seo_description string ≤ 160 lesen und schreiben
og_image id nur lesen
updated_at datetime nur lesen

/api/v1/team/

GETPOSTPUTPATCH

  • Filter member_type is_featured
  • search first_name last_name position specialties
  • ordering order last_name updated_at (Standard order)
FeldFeldtypZugriff
id integer nur lesen
first_name string ≤ 100 lesen und schreiben Pflicht beim Anlegen
last_name string ≤ 100 lesen und schreiben Pflicht beim Anlegen
position string ≤ 150 lesen und schreiben Pflicht beim Anlegen
short_bio string ≤ 300 lesen und schreiben
bio string lesen und schreiben
profile_image file (URL) nur lesen
email email ≤ 254 lesen und schreiben
phone string ≤ 20 lesen und schreiben
linkedin url ≤ 200 lesen und schreiben
github url ≤ 200 lesen und schreiben
twitter url ≤ 200 lesen und schreiben
instagram url ≤ 200 lesen und schreiben
facebook url ≤ 200 lesen und schreiben
website url ≤ 200 lesen und schreiben
specialties string ≤ 200 lesen und schreiben
years_experience integer lesen und schreiben
education string ≤ 200 lesen und schreiben
location string ≤ 100 lesen und schreiben
languages string ≤ 100 lesen und schreiben
member_type choice
founder, lead, senior, developer, designer, manager, consultant, intern
lesen und schreiben
is_featured boolean lesen und schreiben
order integer lesen und schreiben
updated_at datetime nur lesen

/api/v1/testimonials/

GETPOSTPUTPATCH

  • Filter rating
  • search name position testimonial
  • ordering order rating updated_at (Standard order)
FeldFeldtypZugriff
id integer nur lesen
name string ≤ 100 lesen und schreiben Pflicht beim Anlegen
position string ≤ 100 lesen und schreiben Pflicht beim Anlegen
testimonial string lesen und schreiben Pflicht beim Anlegen
rating integer lesen und schreiben
image file (URL) nur lesen
order integer lesen und schreiben
updated_at datetime nur lesen

/api/v1/publications/

GETPOSTPUTPATCH

  • Filter slug category__slug year is_featured
  • search title authors journal abstract
  • ordering order year title updated_at (Standard order,-year)
FeldFeldtypZugriff
id integer nur lesen
slug string ≤ 200 lesen und schreiben
title string ≤ 255 lesen und schreiben Pflicht beim Anlegen
authors string ≤ 255 lesen und schreiben Pflicht beim Anlegen
journal string ≤ 255 lesen und schreiben
year string ≤ 10 lesen und schreiben Pflicht beim Anlegen
abstract string lesen und schreiben
link url ≤ 200 lesen und schreiben
category object nur lesen
category_slug slug nur schreiben
is_featured boolean lesen und schreiben
order integer lesen und schreiben
seo_title string ≤ 70 lesen und schreiben
seo_description string ≤ 160 lesen und schreiben
og_image id nur lesen
updated_at datetime nur lesen

/api/v1/resources/

GETPOSTPUTPATCH

  • Filter slug resource_type is_free
  • search title description
  • ordering order title created_at updated_at (Standard order)
FeldFeldtypZugriff
id integer nur lesen
slug string ≤ 200 lesen und schreiben Pflicht beim Anlegen
title string ≤ 200 lesen und schreiben Pflicht beim Anlegen
description string lesen und schreiben Pflicht beim Anlegen
resource_type choice
guide, ebook, whitepaper, template, checklist, case_study
lesen und schreiben
file file (URL) nur lesen
file_size string nur lesen
thumbnail file (URL) nur lesen
is_free boolean lesen und schreiben
requires_email boolean lesen und schreiben
order integer lesen und schreiben
seo_title string ≤ 70 lesen und schreiben
seo_description string ≤ 160 lesen und schreiben
og_image id nur lesen
created_at datetime nur lesen
updated_at datetime nur lesen

/api/v1/events/

GETPOSTPUTPATCH

  • Filter slug event_type is_online is_featured
  • search title description location
  • ordering start_date title updated_at (Standard -start_date)
FeldFeldtypZugriff
id integer nur lesen
slug string ≤ 200 lesen und schreiben Pflicht beim Anlegen
title string ≤ 200 lesen und schreiben Pflicht beim Anlegen
description string lesen und schreiben Pflicht beim Anlegen
event_type choice
conference, workshop, webinar, seminar, training, meeting
lesen und schreiben
start_date datetime lesen und schreiben Pflicht beim Anlegen
end_date datetime lesen und schreiben Pflicht beim Anlegen
timezone string ≤ 64 lesen und schreiben
location string ≤ 200 lesen und schreiben Pflicht beim Anlegen
is_online boolean lesen und schreiben
meeting_url url ≤ 200 lesen und schreiben
registration_url url ≤ 200 lesen und schreiben
registration_deadline datetime lesen und schreiben
max_attendees integer lesen und schreiben
featured_image file (URL) nur lesen
is_featured boolean lesen und schreiben
order integer lesen und schreiben
seo_title string ≤ 70 lesen und schreiben
seo_description string ≤ 160 lesen und schreiben
og_image id nur lesen
created_at datetime nur lesen
updated_at datetime nur lesen

/api/v1/jobs/

GETPOSTPUTPATCH

  • Filter slug category__slug contract_type remote_option experience_level is_featured is_urgent
  • search title description location skills_required
  • ordering published_date title updated_at (Standard -published_date)
FeldFeldtypZugriff
id integer nur lesen
slug string ≤ 50 lesen und schreiben
title string ≤ 200 lesen und schreiben Pflicht beim Anlegen
description string lesen und schreiben Pflicht beim Anlegen
responsibilities string lesen und schreiben
requirements string lesen und schreiben Pflicht beim Anlegen
qualifications string lesen und schreiben
benefits string lesen und schreiben
category object nur lesen
category_slug slug nur schreiben Pflicht beim Anlegen
location string ≤ 200 lesen und schreiben Pflicht beim Anlegen
contract_type choice
full_time, part_time, contract, freelance, internship, temporary
lesen und schreiben
remote_option choice
onsite, remote, hybrid
lesen und schreiben
experience_level choice
entry, junior, mid, senior, lead, executive
lesen und schreiben
education_level string ≤ 100 lesen und schreiben
languages_required string ≤ 200 lesen und schreiben
skills_required string lesen und schreiben
skills_preferred string lesen und schreiben
tags string ≤ 500 lesen und schreiben
salary_min decimal lesen und schreiben
salary_max decimal lesen und schreiben
salary_currency string ≤ 3 lesen und schreiben
salary_period choice
hour, month, year
lesen und schreiben
expected_start_date date lesen und schreiben
application_deadline date lesen und schreiben
is_active boolean lesen und schreiben
is_featured boolean lesen und schreiben
is_urgent boolean lesen und schreiben
published_date datetime nur lesen
seo_title string ≤ 70 lesen und schreiben
seo_description string ≤ 160 lesen und schreiben
og_image id nur lesen
created_at datetime nur lesen
updated_at datetime nur lesen

/api/v1/faq/

GETPOSTPUTPATCH

  • Filter category__slug is_featured
  • search question answer
  • ordering order updated_at (Standard order)
FeldFeldtypZugriff
id integer nur lesen
question string ≤ 300 lesen und schreiben Pflicht beim Anlegen
answer string lesen und schreiben Pflicht beim Anlegen
category object nur lesen
category_slug slug nur schreiben
is_featured boolean lesen und schreiben
order integer lesen und schreiben
updated_at datetime nur lesen

/api/v1/bookable-items/

GET

FeldFeldtypZugriff
id integer nur lesen
label string nur lesen
duration_minutes integer nur lesen
price decimal nur lesen
currency string nur lesen
updated_at datetime nur lesen

/api/v1/bookings/

POST

FeldFeldtypZugriff
item integer lesen und schreiben Pflicht beim Anlegen
customer_name string ≤ 120 lesen und schreiben Pflicht beim Anlegen
customer_email email lesen und schreiben Pflicht beim Anlegen
customer_phone string ≤ 40 lesen und schreiben
date date lesen und schreiben Pflicht beim Anlegen
time string lesen und schreiben Pflicht beim Anlegen
note string lesen und schreiben

Sicherheitsempfehlungen#

  • Bewahren Sie Schlüssel auf Ihrem Server auf. Verschicken Sie niemals einen Schlüssel in einer mobilen App oder im Browser-Code.
  • Verwenden Sie einen read-Schlüssel überall dort, wo Sie nicht schreiben müssen.
  • Ein Schlüssel pro Integration: Das Widerrufen eines Schlüssels beeinträchtigt die anderen nicht.