Skip to main content

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 Accept header versioning.
  • Future versions would use a new prefix (e.g. /api/v2).

Identifiers

Public identifiers in API responses are not database primary keys:
ResourceID formatExample field
Usersqidid
Companysqidid (path param {company})
Eventslugid (path param {event})
Activationslugid
Formsqidid
Form fieldsqidid
Ordersqidid
Cohostsqidid
Ticket typeslugslug
WebhookUUIDid
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:
{
  "data": [ ... ],
  "links": {
    "first": "https://{domain}/api/v1/{company}/events?page=1",
    "last": "https://{domain}/api/v1/{company}/events?page=3",
    "prev": null,
    "next": "https://{domain}/api/v1/{company}/events?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 3,
    "per_page": 15,
    "to": 15,
    "total": 42
  }
}
Default page size is 15. Use the page query parameter to navigate.

Company context

Most resources are scoped under a company:
GET /api/v1/{company}/events
  • {company} is the company sqid from GET /api/v1/companies.
  • Middleware restricts all queries to that company.
  • The authenticated user must belong to the company.
  • The company must have an active Pro plan (enforced via the USE_API subscription gate).

Subscription gates

API access is a paid feature. In the Animo admin, this is the Pro plan. Subscribe or upgrade at https://app.animo.co/admin/settings/billing.
Internal gateAnimo planRequired for
USE_APIPro (Stripe tier: starter)All company-scoped REST resources (events, forms, orders, etc.)
USE_INTEGRATIONSPro and aboveWebhook attach/update/detach
Free and Business plans do not grant API access. Upgrade at https://app.animo.co/admin/settings/billing.

Entitlement behavior

EndpointWithout Pro plan
GET /api/v1/companies200 with empty data: [] — looks like “no companies”, not a permission error
GET /api/v1/{company}/… (and other company-scoped routes)403 Forbidden
If your token is valid but GET /companies returns an empty list, check the company’s plan before debugging scopes or token setup.

Public URLs

The API does not return public-facing URLs in responses today. Construct them from slugs in the API response.

Event page

https://app.animo.co/{company-slug}/event/{event-slug}
SegmentAPI source
{company-slug}slug from GET /api/v1/companies
{event-slug}id from event resources

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:
https://app.animo.co/{company-slug}/event/{event-slug}/{ticket-type-slug}
SegmentSourceAPI field
{company-slug}Company URL slugslug on GET /api/v1/companies
{event-slug}Event URL slugid on event resources
{ticket-type-slug}Ticket type slugslug on ticket type resources
Optional query parameter:
ParameterDescription
qtyPre-select ticket quantity on the signup page (e.g. ?qty=1)
Example:
https://app.animo.co/aidemodays/event/ai-demo-days-hr-edition/general-admission?qty=1
The ticket signup flow continues at /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:
https://app.animo.co/{company-slug}/event/{event-slug}/o/{order-id}/checkout
SegmentAPI source
{order-id}id from the order resource (sqid)
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 activation slug 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):
https://app.animo.co/{company-slug}/{activation-slug}
Event-scoped (when the activation is linked to an event):
https://app.animo.co/{company-slug}/{event-slug}/{activation-slug}
SegmentAPI source
{company-slug}slug from GET /api/v1/companies
{activation-slug}id or slug from GET /api/v1/{company}/activations
{event-slug}id from the linked event (not returned on ActivationResource — see below)
Unlike tickets, event activations do not use /event/ in the path — it’s /{company}/{event}/{activation}, not /{company}/event/{event}/{activation}.
Sub-paths (the flow, same as tickets): the base URLs above are the entry point. /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)

ResourceOn createOn update
Eventid/slug derived from name — supplied slug is ignoredslug can be changed via PATCH
Ticket typeSupplied slug is honoredslug can be changed via PATCH

Timestamps (actual format)

Responses use ISO 8601 datetimes with a +00:00 UTC offset, not a Z suffix:
2026-04-25T09:00:00.4040+00:00
Fractional-second precision is variable (e.g. .4040, .011, .088). Do not assume exactly three millisecond digits. Parse as ISO 8601 with flexible fractional seconds.

Search filter

Several list endpoints support a q query parameter for case-sensitive substring search:
EndpointSearches
GET /api/v1/{company}/activationstitle
GET /api/v1/{company}/eventsname
GET /api/v1/{company}/formsname

Optional includes

Query parameterEndpointsEffect
include_formTicket type list/showEmbeds the related form and fields
include_submissionOrder list/showEmbeds submission (with form and answers) and lead

Request bodies

  • Send JSON with Content-Type: application/json.
  • PATCH endpoints accept partial updates — only include fields you want to change.
  • POST create endpoints use paths like /create (e.g. POST /api/v1/{company}/events/create).

Validation errors

Invalid request bodies return 422 Unprocessable Entity:
{
  "message": "The name field is required. (and 1 more error)",
  "errors": {
    "name": [
      "The name field is required."
    ],
    "date_start": [
      "The date start field is required."
    ]
  }
}
Refer to each endpoint page for field requirements and validation rules.

Response envelope

Single resources are wrapped in a data key:
{
  "data": {
    "id": "my-event",
    "name": "My Event"
  }
}
Collections (non-paginated) follow the same pattern. Paginated collections use the structure described in Pagination.