Concepten
Fouten
Elke weigering is een RFC 9457-probleem met een vaste code. Vertak op de code; toon de toelichting aan een mens.
Hoe een probleem eruitziet
Als de API een aanroep weigert, antwoordt hij met een status van 400 of hoger en een body in application/problem+json, zoals RFC 9457 die beschrijft:
{
"type": "https://attendbeacon.com/developers/errors#moduleOff",
"title": "The module is switched off",
"status": 409,
"detail": "The Sponsors module is switched off for this event. Its organiser can switch it on under the event's Modules; nothing was deleted.",
"instance": "/api/v1/events/b3ac0000-0000-4000-8000-000000000001/sponsors",
"code": "moduleOff",
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"module": "sponsors",
"error": "The Sponsors module is switched off for this event. ..."
}codeis waar je software op vertakt. Codes liggen vast: eenmaal uitgebracht, worden ze nooit hernoemd.detailis een zin voor een mens: toon hem in je logboek of je interface.typelinkt naar de rij van de code in de tabel hieronder.traceIdhelpt de support van AttendBeacon de aanroep te vinden; stuur hem mee als je een vraag stelt.- Sommige codes geven meer mee:
scope(de scope die een sleutel mist),module,errors(elk veld dat niet klopt),etag,taken,sessions. errorherhaaltdetailvoor flows die vóór problem details zijn gebouwd. Hij blijft in v1; nieuwe code leestdetail.
Velden die niet kloppen
invalidRequest noemt elk veld met wat eraan mankeert, zodat een formulier de melding naast het veld kan tonen:
{
"status": 400,
"code": "invalidRequest",
"detail": "Some fields are not right; errors names each.",
"errors": [
{ "field": "startDate", "message": "startDate is a date such as 2026-11-12." },
{ "field": "timeZone", "message": "timeZone is an IANA zone such as Europe/Amsterdam." }
]
}Een geweigerde registratie noemt ook de deelnemer, vanaf 0, met een code voor wat er mis is: { "attendee": 0, "field": "email", "code": "notEmail" }.
Wat je opnieuw probeert
| Status | Opnieuw proberen? |
|---|---|
| 400, 401, 403, 404, 409, 412, 422 | Nee: hetzelfde verzoek wordt opnieuw geweigerd. Los het eerst op. |
| 429 | Ja, na het aantal seconden in Retry-After. Zie Limieten. |
| 500, 502, 503, 504 | Ja, een paar keer met een steeds langere wachttijd, en bij een POST met dezelfde Idempotency-Key. Zie Idempotentie. |
Alle codes
| Code | Status | Wat het betekent en wat je doet |
|---|---|---|
invalidKey | 401 | No working API key. No key was sent, or it is not one this platform made. Send it as Authorization: Bearer abk_... or in X-Api-Key. |
keyExpired | 401 | The key has expired. The key's expiry date has passed. Make a new key in the workspace under Integrations, API & MCP. |
keyRevoked | 401 | The key was revoked. Somebody revoked the key in the workspace. Make a new key. |
wrongAudience | 401 | A token for another resource. A token an assistant got by signing in works where it was issued for: the MCP server (/mcp) or the REST API (/api/v1). |
invalidOrigin | 403 | Not from this origin. The MCP server takes browser requests from AttendBeacon's own origin only; servers and command-line clients send no Origin. |
missingScope | 403 | The key lacks a scope. The key works but may not do this; scope names the scope it needs. Scopes are chosen when a key is made. |
peopleScope | 403 | Personal data needs people:read. This call is about people by name or address, which needs the people:read scope as well. |
notFound | 404 | Not found. There is no such resource in this key's workspace. Another workspace's ids read as not found. |
eventNotFound | 404 | No such event. There is no such event in this key's workspace. |
attendeeNotFound | 404 | No such attendee. There is no such attendee at this event. |
noDoor | 404 | No such door. There is no such door at this event. |
moduleOff | 409 | The module is switched off. The event's organiser switched this feature off under the event's Modules; module names it. Nothing was deleted: switched on again, its data is back. |
onlineEvent | 409 | An online event has no doors. Check-in and other door features do not apply to an online event. |
alreadyCancelled | 409 | Already cancelled. The ticket is already cancelled. |
clash | 409 | The room is taken. Another session is in the room at that time; sessions names it. Send allowClash: true to place it anyway. |
slugTaken | 409 | The address is taken. Another event already has this slug. |
historyNeedsLicence | 409 | A licence is needed first. Reopening an earlier edition above the free limit needs its licence, bought in the workspace. |
endsCommunity | 409 | This would end the community status. A paid ticket ends an event's free community status above the free limit; confirm in the workspace. |
codeTaken | 409 | The code exists. The event already has a discount code with these letters. |
capacityBelowTaken | 409 | Capacity below what is sold. The capacity would be lower than the places already taken; taken says how many. |
idempotencyKeyInUse | 409 | The same request is still running. A request with this Idempotency-Key is still being handled. Wait a moment and send it again. |
preconditionFailed | 412 | Changed since you read it. If-Match does not name the resource as it is now: somebody changed it. Read it again, then send the change. |
idempotencyKeyReused | 422 | Idempotency-Key used for another request. This Idempotency-Key was used within 24 hours for a request with another method, path or body. Use a new key for a new request. |
invalidRequest | 400 | The request is not valid. A field or parameter is missing or wrong; errors names each, with what is wrong. |
invalidBody | 400 | The body is not readable. The body is not JSON, or a field has the wrong type. |
invalidCursor | 400 | The cursor is not valid. Pass nextCursor exactly as a list returned it, with the same filters. |
invalidUpdatedSince | 400 | updatedSince is not a moment. updatedSince is an ISO 8601 moment such as 2026-10-09T08:00:00Z. |
invalidSort | 400 | Unknown sort. sort is changed (oldest change first, the default) or -created (newest first). |
invalidIdempotencyKey | 400 | Idempotency-Key is not valid. An Idempotency-Key is 1 to 255 visible ASCII characters; a UUID is a good one. |
invalid | 400 | An attendee's details are not right. errors names which attendee (from 0) and which field: firstName, lastName, email, company, jobTitle or a question id, with what is wrong (required, tooLong, notEmail, notOption). |
soldOut | 400 | Sold out. The ticket type has no places left; ticketTypeId names it. Sent as 400 since v1 began, kept so for flows that branch on it. |
unknownTicket | 400 | No such ticket type. ticketTypeId is not a ticket type of this event. |
empty | 400 | Nobody to register. Send at least one attendee. |
tooMany | 400 | Too many at once. At most 50 attendees in one request; send more requests. |
registrationRefused | 400 | The registration was refused. Another reason the order was refused; reason says which, such as addOnSoldOut or namesLaterNotOffered. |
eventType | 400 | Not an event type. event is one of the webhook event types (GET /webhooks/event-types). |
webhookUrl | 400 | Not an address. url is an absolute https address without user name or fragment, at most 2,000 characters. |
webhookHttps | 400 | Not https. url must be https. |
webhookPrivate | 400 | Not a public address. url points at a private, loopback or link-local address, which AttendBeacon never calls. |
tooManyHooks | 400 | Too many subscriptions. A workspace has at most 200 automation subscriptions. Switch off flows or Zaps it no longer needs. |
tooManyEndpoints | 400 | Too many webhook endpoints. A workspace has at most 20 webhook endpoints. Remove one it no longer needs. |
webhooksUnavailable | 503 | Webhooks are not available here. This deployment keeps no signing secrets, so endpoints cannot be added or given a new secret. |
demoWorkspace | 403 | The demonstration is read-only. The demonstration workspace cannot be changed through the API. |
rateLimited | 429 | Too many requests. The key made more than its calls a minute. Retry-After says when to try again; RateLimit says what is left. |
serverError | 500 | Something went wrong here. An error on AttendBeacon's side. Retry with the same Idempotency-Key; traceId helps support find it. |
Ermee omgaan
const response = await fetch(url, { headers });
if (!response.ok) {
const problem = await response.json();
switch (problem.code) {
case "rateLimited":
await new Promise((resolve) => setTimeout(resolve, Number(response.headers.get("Retry-After")) * 1000));
break; // and try again
case "moduleOff":
console.warn(`Skipping: ${problem.module} is switched off for this event.`);
break;
default:
throw new Error(`${problem.code}: ${problem.detail} (trace ${problem.traceId})`);
}
}if (!response.IsSuccessStatusCode)
{
var problem = await response.Content.ReadFromJsonAsync<JsonElement>();
var code = problem.GetProperty("code").GetString();
if (code == "rateLimited")
{
await Task.Delay(response.Headers.RetryAfter?.Delta ?? TimeSpan.FromSeconds(30));
// and try again
}
else
{
throw new InvalidOperationException($"{code}: {problem.GetProperty("detail").GetString()} (trace {problem.GetProperty("traceId").GetString()})");
}
}if not response.ok:
problem = response.json()
if problem["code"] == "rateLimited":
time.sleep(int(response.headers.get("Retry-After", "30")))
# and try again
elif problem["code"] == "moduleOff":
print(f"Skipping: {problem['module']} is switched off for this event.")
else:
raise RuntimeError(f"{problem['code']}: {problem['detail']} (trace {problem['traceId']})")try {
$data = Invoke-RestMethod -Uri $url -Headers $headers
} catch {
$problem = $_.ErrorDetails.Message | ConvertFrom-Json
if ($problem.code -eq "rateLimited") { Start-Sleep -Seconds 30 } # and try again
else { throw "$($problem.code): $($problem.detail) (trace $($problem.traceId))" }
}