TillyGen API

REST API for enterprise workspaces: read and write access to projects, tasks, crew, equipment, shooting schedules and more. All responses are JSON, all IDs are UUIDs, timestamps are ISO 8601.

The machine-readable spec lives at /api/v1/openapi.json (OpenAPI 3.1).

Die maschinenlesbare Spec liegt unter /api/v1/openapi.json (OpenAPI 3.1).

BASEhttps://app.tillygen.com/api/v1

Authentication

Every request needs an API key as a bearer token. Keys are created in TillyGen under Settings → API (Enterprise plan, Owner or Admin) and start with tg_live_. The plain text is shown exactly once at creation — TillyGen stores only a hash.

Jede Anfrage braucht einen API-Key als Bearer-Token. Keys werden in TillyGen unter Einstellungen → API erstellt (Enterprise-Plan, Owner oder Admin) und beginnen mit tg_live_. Der Klartext wird genau einmal beim Erstellen angezeigt — TillyGen speichert nur einen Hash.

curl -H "Authorization: Bearer tg_live_…" \
  "https://app.tillygen.com/api/v1/me"

A key belongs to exactly one workspace and has one of two permissions: read-only (GET only) or read-write (also POST, PATCH, DELETE). Writes run under the account of the key's creator — activities and notifications behave like changes made in the app.

Ein Key gehört zu genau einem Workspace und hat eine von zwei Berechtigungen: read-only (nur GET) oder read-write (auch POST, PATCH, DELETE). Schreibzugriffe laufen unter dem Konto des Key-Erstellers — Aktivitäten und Benachrichtigungen verhalten sich wie bei Änderungen in der App.

Key context (/me)

Bootstrap endpoint for integrations: returns the key prefix, permission and the key's workspace.

GET/api/v1/me

Example response

{
  "data": {
    "key_prefix": "tg_live_a1b2",
    "permission": "read_write",
    "workspace": { "id": "…", "name": "…" }
  }
}

Errors

Errors respond with a uniform JSON body. error is a machine-readable code, request_id identifies the request for support cases (also sent as the x-request-id header on every response). Validation errors carry the affected fields in details.

Fehler antworten mit einem einheitlichen JSON-Body. error ist ein maschinenlesbarer Code, request_id identifiziert die Anfrage für Support-Fälle (auch als Header x-request-id auf jeder Antwort). Validierungsfehler tragen die betroffenen Felder in details.

{
  "error": "validation_failed",
  "message": "…",
  "details": [{ "path": "name", "code": "too_small", "message": "…" }],
  "request_id": "9f0e…"
}

Error codes

StatusCodeMeaning
400invalid_bodyRequest body is not valid JSON or violates the schema.
400invalid_cursorThe cursor parameter is unreadable or invalid.
400invalid_filterA query filter has an invalid value (e.g. not a UUID).
401missing_authorizationAuthorization header is missing or is not a bearer token.
401invalid_keyThe API key is unknown.
401key_revokedThe API key has been revoked.
403not_enabledThe API is not enabled for this workspace (Enterprise plan required).
403read_only_keyWrite operation with a read-only key.
403key_creator_inactiveThe key's creator is no longer an active member of the workspace.
403forbiddenThe operation is not allowed for this resource or role.
404not_foundResource does not exist or lies outside the key's workspace.
404unknown_resourceUnknown resource path.
405method_not_allowedHTTP method not supported for this route.
409conflictUniqueness or reference rule violated (e.g. a timer is already running).
409duplicate_numberProject number already taken.
422validation_failedValidation failed (see the details array).
429rate_limitedRate limit reached — check the Retry-After header.
500server_errorUnexpected server error — include the request_id when contacting support.
503unavailableService temporarily unavailable.

Pagination

Lists are cursor-paginated and always sorted by creation time, descending. limit is optional (default 50, maximum 100). If the response contains next_cursor, there are more pages — pass the value unchanged as cursor.

Listen sind cursor-basiert paginiert und immer absteigend nach Erstellzeitpunkt sortiert. limit ist optional (Standard 50, Maximum 100). Enthält die Antwort next_cursor, gibt es weitere Seiten — den Wert unverändert als cursor übergeben.

GET /api/v1/clients?limit=50
→ { "data": [ … ], "next_cursor": "MjAyNi0wOC0…" }

GET /api/v1/clients?limit=50&cursor=MjAyNi0wOC0…

Rate limits

Each API key is allowed 120 requests per minute, each IP address 480. Beyond that the API responds with 429 rate_limited and a Retry-After header in seconds.

Pro API-Key sind 120 Anfragen pro Minute erlaubt, pro IP-Adresse 480. Darüber antwortet die API mit 429 rate_limited und einem Retry-After-Header in Sekunden.

Browse the API