SwaySway

Référence des endpoints

Référence complète de tous les endpoints de l'API publique Sway v1.

Référence des endpoints

Tous les endpoints sont accessibles sous https://www.sway.events/api/v1 et sont limités au crew propriétaire de la clé API. Tous sont en lecture seule, sauf POST /v1/booking-requests.

#EndpointScope
1GET /v1/me
2GET /v1/crewread:profile
3GET /v1/artistsread:artists
4GET /v1/artists/{id}read:artists
5GET /v1/artists/{id}/eventsread:artists + read:events
6GET /v1/promotersread:promoters
7GET /v1/promoters/{id}read:promoters
8GET /v1/promoters/{id}/eventsread:promoters + read:events
9GET /v1/eventsread:events
10GET /v1/events/{id}read:events
11GET /v1/events/{id}/ticket-tiersread:events
12GET /v1/venues/{id}read:venues
13POST /v1/booking-requestswrite:bookings

Les endpoints de liste (/v1/artists, /v1/promoters, /v1/events, et les deux sous-flux d'événements) utilisent l'enveloppe standard { data, pagination } et la pagination par curseur — voir Pagination & filtres. Chaque endpoint de ressource unique, ainsi que POST /v1/booking-requests, renvoie l'objet directement — sans enveloppe data.


Clé & crew

GET /v1/me

Scope : aucun. Introspection de la clé — le test « ma clé est-elle vivante ». Renvoie la key identifiée (id, scopes, limites de débit) et son crew.

{
  "key": {
    "id": "3f9a1c02-7b45-4c8e-9d21-0a1b2c3d4e5f",
    "scopes": ["read:profile", "read:artists", "read:promoters", "read:events", "read:venues"],
    "rate_limit": { "per_minute": 120, "per_day": 20000 }
  },
  "crew": { "id": "a2628d53-4f21-4c1e-9b7d-1a2b3c4d5e6f", "name": "Insomnia", "slug": "insomnia" }
}

GET /v1/crew

Scope : read:profile. Le profil du crew plus un résumé de ses pages gérées, imbriqué sous pages sous forme de tableaux d'ids.

{
  "id": "a2628d53-4f21-4c1e-9b7d-1a2b3c4d5e6f",
  "name": "Insomnia",
  "slug": "insomnia",
  "pages": {
    "artists": [245, 512],
    "promoters": [697]
  }
}

Artistes

GET /v1/artists

Scope : read:artists. Le roster — tous les artistes gérés par votre crew, en représentation complète. Triés par name croissant. Les artistes du roster sont renvoyés même s'ils ne sont pas publiés.

Paramètres de requête : cursor, limit (1–100, défaut 25).

{
  "data": [
    {
      "id": 245,
      "name": "KROMATIEK",
      "image_url": "https://assets.sway.events/artists/245/cover.webp",
      "description": "Artiste techno basé à Gand…",
      "genres": ["Techno", "Hard Groove"],
      "links": {
        "spotify": "https://open.spotify.com/artist/…",
        "instagram": "https://instagram.com/kromatiek"
      },
      "is_verified": true,
      "managed": true,
      "contact_emails": [{ "type": "booking", "value": "[email protected]" }]
    }
  ],
  "pagination": { "next_cursor": "eyJrIjoiS1JPTUFUSUVLIiwiaWQiOjI0NX0", "has_more": true, "limit": 25 }
}

Les emails de contact vivent dans le tableau dédié contact_emails (niveau géré uniquement) ; links ne contient jamais de clé email. Les artistes étrangers (niveau public) n'ont pas de contact_emails.

GET /v1/artists/{id}

Scope : read:artists. Représentation complète d'un artiste géré, renvoyée directement (sans enveloppe) — même forme qu'une entrée du roster ci-dessus. Les artistes étrangers (invités du lineup) renvoient 404 — ils n'apparaissent qu'intégrés dans les lineups d'événements.

GET /v1/artists/{id}/events

Scope : read:artists et read:events (les deux requis). L'historique et le calendrier des dates de l'artiste : événements publiés où l'artiste est un membre confirmé du lineup. Chaque élément est un résumé d'événement portant une référence venue légère ({ id, name } ou null).

Paramètres de requête : status (upcoming | past | all, défaut upcoming), cursor, limit. Ce flux n'accepte pas from/to ni expand.


Promoteurs

GET /v1/promoters

Scope : read:promoters. Tous les promoteurs gérés par votre crew, en représentation complète. Même enveloppe et paramètres que /v1/artists.

GET /v1/promoters/{id}

Scope : read:promoters. Représentation complète d'un promoteur géré et publié, renvoyée directement (sans enveloppe). Gérés uniquement — sinon 404.

GET /v1/promoters/{id}/events

Scope : read:promoters et read:events (les deux requis). Le flux d'événements d'un promoteur — le flux principal d'un site partenaire. Chaque événement porte par défaut une référence venue légère ({ id, name } ou null) ; utilisez expand pour intégrer davantage.

Paramètres de requête : status (upcoming | past | all, défaut upcoming), from / to (ISO 8601), expand (n'importe quel sous-ensemble de venue,lineup,ticket_tiers séparé par des virgules), cursor, limit. expand=venue fait passer la référence de salle à la salle complète de niveau public.


Événements

GET /v1/events

Scope : read:events. Flux combiné : les événements de vos promoteurs gérés plus les événements publiés où figurent vos artistes du roster. Chaque élément est un résumé d'événement avec une référence venue légère ({ id, name } ou null).

Paramètres de requête : promoter_id, artist_id, status (défaut upcoming), from / to (ISO 8601), cursor, limit. Ce flux ne supporte pas expand — le passer renvoie 400 validation_error. Utilisez /v1/events/{id} ou /v1/promoters/{id}/events pour des données étendues.

GET /v1/events/{id}

Scope : read:events. Un événement publié dans le graphe de votre crew, renvoyé directement (sans enveloppe). venue (niveau public complet) et lineup sont toujours intégrés ; les genres sont toujours présents. Ajoutez ?expand=ticket_tiers pour inclure aussi les catégories de billets.

Paramètres de requête : expand — accepte un sous-ensemble de venue,lineup,ticket_tiers séparé par des virgules (venue et lineup étant déjà intégrés, seul ticket_tiers ajoute quelque chose).

Les entrées du lineup portent le DTO artiste plus stage, start_time, end_time et un artist_id, et incluent l'indicateur managed : vos propres artistes arrivent en représentation complète (avec contact_emails), les invités étrangers apparaissent au niveau public uniquement. Les artistes personnalisés (non liés) apparaissent comme des entrées de remplacement avec artist_id: null.

{
  "id": 4521,
  "title": "Overload",
  "description": "",
  "starts_at": "2026-09-12T22:00:00Z",
  "ends_at": "2026-09-13T06:00:00Z",
  "timezone": "Europe/Brussels",
  "image_url": "https://assets.sway.events/events/4521/cover.webp",
  "type": "club",
  "page_url": "https://www.sway.events/event/4521",
  "venue": {
    "id": 88,
    "name": "Jungle Bar",
    "image_url": "",
    "description": "",
    "location": { "address": "Nieuwewandeling 2, Ghent" },
    "genres": [],
    "links": null
  },
  "lineup": [
    { "stage": "Main", "start_time": "23:00", "end_time": "01:00", "artist_id": 245, "id": 245, "name": "KROMATIEK", "image_url": "", "description": "", "genres": ["Techno"], "links": { "spotify": "" }, "is_verified": true, "managed": true, "contact_emails": [{ "type": "booking", "value": "[email protected]" }] },
    { "stage": null, "start_time": null, "end_time": null, "artist_id": 1042, "id": 1042, "name": "CE$AR", "image_url": "", "description": null, "genres": ["House"], "links": null, "is_verified": false, "managed": false }
  ],
  "genres": ["Techno"]
}

GET /v1/events/{id}/ticket-tiers

Scope : read:events. Les catégories de billets de l'événement : nom, description, prix, statut, fenêtres de vente et un lien profond checkout_url vers le checkout Sway. Pas de compteurs de stock, pas de commandes, pas de données acheteurs. C'est une petite liste fixe — elle est enveloppée dans { "data": [ … ] } mais n'a pas d'objet pagination ni de curseur.

{
  "data": [
    {
      "id": "301",
      "name": "Early Bird",
      "description": "Première salve limitée",
      "price": 15.0,
      "currency": "EUR",
      "status": "sold_out",
      "sale_start": "2026-06-01T10:00:00Z",
      "sale_end": "2026-07-01T10:00:00Z",
      "max_per_order": 4,
      "checkout_url": "https://www.sway.events/event/4521?ref=api"
    },
    {
      "id": "302",
      "name": "Regular",
      "description": null,
      "price": 20.0,
      "currency": "EUR",
      "status": "on_sale",
      "sale_start": "2026-07-01T10:00:00Z",
      "sale_end": "2026-09-12T22:00:00Z",
      "max_per_order": 6,
      "checkout_url": "https://www.sway.events/event/4521?ref=api"
    }
  ]
}

status est dérivé côté serveur et vaut on_sale, scheduled, sold_out ou off_sale. currency vaut EUR par défaut.


Salles

GET /v1/venues/{id}

Scope : read:venues. Niveau public uniquement, renvoyé directement (sans enveloppe) : id, name, image_url, description, location (objet — adresse plus données géo éventuelles, ou null), genres, links (null si vide). Les salles ne sont accessibles que lorsqu'elles accueillent un événement publié du graphe de votre crew — sinon 404.

{
  "id": 88,
  "name": "Jungle Bar",
  "image_url": "https://assets.sway.events/venues/88/cover.webp",
  "description": "",
  "location": { "address": "Nieuwewandeling 2, Ghent" },
  "genres": [],
  "links": null
}

Demandes de booking

POST /v1/booking-requests

Scope : write:bookings (opt-in à la création de la clé). Envoie une demande de booking depuis un site partenaire vers le pipeline de booking du crew et déclenche une notification. Cet endpoint a une limite de débit plus stricte que les endpoints de lecture (10 requêtes / minute, par IP).

Corps de la requête — un objet JSON plat :

ChampTypeRequisNotes
artist_idsnumber[]ouiNon vide, 50 ids max, chacun étant un artiste géré du roster de votre crew
contact_emailstringouiEmail valide, ≤ 320 caractères
contact_namestringnon≤ 200 caractères
contact_phonestringnon≤ 200 caractères
event_namestringnon≤ 200 caractères
event_datestringnonDate ISO YYYY-MM-DD
venuestringnon≤ 200 caractères
citystringnon≤ 200 caractères
fee_offerstringnonTexte libre, ≤ 200 caractères
capacitystringnonTexte libre, ≤ 200 caractères
ticket_pricestringnonTexte libre, ≤ 200 caractères
organizationstringnon≤ 200 caractères
{
  "artist_ids": [245],
  "contact_email": "[email protected]",
  "contact_name": "Jane Doe",
  "contact_phone": "+32 470 00 00 00",
  "event_name": "Warehouse Night",
  "event_date": "2026-11-21",
  "venue": "Fuse",
  "city": "Brussels",
  "fee_offer": "800 EUR",
  "capacity": "1200",
  "ticket_price": "20 EUR",
  "organization": "Nightlife BV"
}

Réponse 201 Created — renvoyée directement, sans enveloppe :

{
  "id": "9f2c1a7e-4d3b-4e21-8c7a-1b2c3d4e5f60",
  "status": "new",
  "created_at": "2026-07-03T14:00:00Z"
}

Un corps invalide renvoie 422 validation_error (avec un tableau errors). Les artist_ids qui ne font pas partie du roster de votre crew sont rejetés avec 422 et listés sous errors[].invalid_ids.