Conventions
Cross-cutting rules that apply across all Animo API v1 endpoints.Base URL and versioning
- All endpoints are prefixed with
/api/v1. - Versioning is URL-based only. There is no
Acceptheader versioning. - Future versions would use a new prefix (e.g.
/api/v2).
Identifiers
Public identifiers in API responses are not database primary keys:
Use the
id (or slug for ticket types) returned by the API in subsequent requests. Route model binding resolves these public identifiers automatically.
Timestamps
Datetime fields in responses use ISO 8601 with a+00:00 offset. See Timestamps (actual format) for the real shape — do not assume a Z suffix or fixed millisecond width.
Input format for event dates (create/update) uses a separate format: Y-m-d H:i (e.g. 2026-04-25 09:00).
Pagination
List endpoints return Laravel’s standard paginated JSON:page query parameter to navigate.
Company context
Most resources are scoped under a company:{company}is the company sqid fromGET /api/v1/companies.- Middleware restricts all queries to that company.
- The authenticated user must belong to the company.
- API access is available on all plans, including Free.
Subscription gates
Public URLs
The API does not return public-facing URLs in responses today. Construct them from slugs in the API response.Event page
Ticket signup page
Ticket types created via the API can be linked on the public Animo ticket shop. These URLs are separate from the API base URL and use slugs, not sqids. Pattern:
Optional query parameter:
Example:
/form on the same path when a registration form is attached to the ticket type.
Order checkout page (paid tickets)
After creating a paid order via the API, send the attendee to Mollie checkout:paid_at remains null until Mollie payment succeeds (async webhook).
Activation form page
To embed or link an Animo-hosted activation form (sponsorship, waitlist, contact) from a custom site, get the activationslug from GET /api/v1/{company}/activations. There are two URL variants. Prefer the company-scoped URL by default — it always works for published activations. Use the event-scoped form only when you need to attribute the signup to a specific event.
Company-scoped (default):
Unlike tickets, event activations do not useSub-paths (the flow, same as tickets): the base URLs above are the entry point./event/in the path — it’s/{company}/{event}/{activation}, not/{company}/event/{event}/{activation}.
/form (form step) and /thank-you (confirmation) are reached after sign-up — link cold traffic to the base URL, not /form; visitors who hit /form without signing up are redirected back to the base URL. An event-scoped URL whose activation isn’t actually attached to that event also redirects to the company-scoped URL.
API gap: ActivationResource does not expose the linked event’s slug, so you can’t build the event-scoped URL from GET /activations alone — fetch the event slug from GET /events, or use the company-scoped URL, which always works.
Slug behavior (events vs ticket types)
Timestamps (actual format)
Responses use ISO 8601 datetimes with a+00:00 UTC offset, not a Z suffix:
.4040, .011, .088). Do not assume exactly three millisecond digits. Parse as ISO 8601 with flexible fractional seconds.
Search filter
Several list endpoints support aq query parameter for case-sensitive substring search:
Optional includes
Request bodies
- Send JSON with
Content-Type: application/json. PATCHendpoints accept partial updates — only include fields you want to change.POSTcreate endpoints use paths like/create(e.g.POST /api/v1/{company}/events/create).
Validation errors
Invalid request bodies return422 Unprocessable Entity:
Response envelope
Single resources are wrapped in adata key: