Falcon Operations REST API v1

Base URL: https://operations.wearefalcon.tv/api/v1
Format: JSON; multipart form data for file uploads
Authentication: user-created Falcon Operations Bearer tokens

Overview

The Falcon Operations REST API is the supported integration surface for managing Operations workspaces, productions, people and assets, bookings and handover, production planning data, notes and files. It uses the same workspace roles, access groups, production filters, module permissions and license limits as the Falcon Operations web app.

Use this API for scheduling tools, production dashboards, inventory integrations, automation services, migration scripts and other server-to-server workflows that need concrete Operations data.

Writes affect live Operations data. Test against non-critical data first, create a separate token per integration and grant only the scopes the integration needs.

Public REST API vs the browser API

SurfaceUseAuthenticationStability
/api/v1External integrations and automation.Bearer token with explicit scopes.Versioned public contract.
Unversioned /api/*Falcon Operations web application.Falcon login session and CSRF token.Internal; do not integrate against it.

Falcon Rundown Gateway/MOS APIs solve published-rundown and media exchange workflows. Use this Operations REST API for Operations management data.

Authentication and token lifecycle

Every REST endpoint requires a Bearer token:

Authorization: Bearer fo_live_...

Create tokens in Falcon Operations from the footer user menu under API Tokens. Enter a descriptive name, choose scopes and optionally set an expiry. Falcon shows the full token once and stores only an HMAC-SHA-256 hash. The dialog shows each token's prefix, scopes, expiry, last use and state, and lets the owner revoke it.

export FALCON_OPERATIONS_TOKEN='fo_live_...'

curl \
  -H "Authorization: Bearer $FALCON_OPERATIONS_TOKEN" \
  https://operations.wearefalcon.tv/api/v1/me
Recommended practice. Keep tokens in a secret manager or environment variable, set an expiry for temporary integrations, and revoke unused tokens immediately.

Scopes

Write scopes also grant the matching read permission. Scopes do not bypass the token user's normal Falcon permissions.

workspaces:read/writeRead, create and manage workspaces.
members:read/writeRead members and manage members/access groups.
productions:read/writeRead and manage productions.
resources:read/writeRead and manage non-login people/resources.
assets:read/writeEquipment, vehicles, spaces and locations.
bookings:read/writeBookings, checkout and return.
tasks:read/writeProduction tasks.
calendar:read/writeProduction calendar events.
call-sheets:read/writeCall sheets/production plans.
crew:read/writeProduction crew assignments.
budgets:read/writeAccounts, budget sheets and rows.
guests:read/writeGuest contacts and guest bookings.
notes:read/writeTag notes, notebooks and rich notes.
files:read/writeFile metadata, upload, download and deletion.

Roles and access rules

LayerREST behaviour
Token scopeThe token must include the endpoint's scope. A missing scope returns 403 scope_required.
Falcon accountThe token owner must still be an active Falcon user with Operations access.
Workspace roleowner and superuser perform administration; workspace deletion is owner-only.
Access groupModule access can be rw, ro or none. Selected-production filters are enforced.
LicenseWorkspace feature and quota checks are identical to the app.

Opaque IDs and field names

REST responses use opaque public IDs and snake_case JSON fields. Sequential database IDs and legacy browser-route IDs are never part of the public contract.

usr_ user
wsp_ workspace
agp_ access group
prj_ production
res_ resource
eqp_ equipment
veh_ vehicle
spc_ space
loc_ location
bkg_ booking
tsk_ task
evt_ event
csh_ call sheet
crm_ crew assignment
acc_ budget account
bsh_ budget sheet
bgr_ budget row
gst_ guest
gbk_ guest booking
csp_ call sheet person
cse_ call sheet equipment
csv_ call sheet vehicle
css_ schedule item
csc_ call sheet contact
nte_ tag note
pnb_ notebook
pnp_ rich note
fil_ file

Responses, pagination and errors

Single resource

{
  "data": {
    "id": "prj_...",
    "workspace_id": "wsp_...",
    "name": "Summer campaign"
  }
}

List

{
  "data": [],
  "meta": {
    "count": 0,
    "limit": 100,
    "offset": 0
  }
}

List endpoints accept limit (1-200), offset, and resource-specific search and status filters. Bookings also accept production_id.

Error

{
  "error": {
    "code": "scope_required",
    "message": "Token scope tasks:write is required.",
    "request_id": "..."
  }
}

Deletes return 204 No Content.

Endpoint summary

Current user and workspaces

MethodPathPurpose
GET/meToken user and accessible workspaces.
GET / POST/workspacesList or create workspaces.
GET / PATCH / DELETE/workspaces/{workspace_id}Read, update or delete a workspace.

Members and access groups

MethodPath
GET / POST/workspaces/{workspace_id}/members
PATCH / DELETE/workspaces/{workspace_id}/members/{user_id_or_email}
GET / POST/workspaces/{workspace_id}/access-groups
GET / PATCH / DELETE/workspaces/{workspace_id}/access-groups/{access_group_id}

Productions

MethodPath
GET / POST/workspaces/{workspace_id}/productions
GET / PATCH / DELETE/productions/{production_id}
POST / DELETE/productions/{production_id}/archive

Resources and assets

CollectionList/createRead/update/delete
Resources/workspaces/{workspace_id}/resources/resources/{resource_id}
Equipment/workspaces/{workspace_id}/equipment/equipment/{equipment_id}
Vehicles/workspaces/{workspace_id}/vehicles/vehicles/{vehicle_id}
Spaces/workspaces/{workspace_id}/spaces/spaces/{space_id}
Locations/workspaces/{workspace_id}/locations/locations/{location_id}
GET/locations/{location_id}/contents?include_children=true

Bookings and handover

MethodPath
GET / POST/workspaces/{workspace_id}/bookings
GET / PATCH / DELETE/bookings/{booking_id}
POST/bookings/{booking_id}/checkout
POST/bookings/{booking_id}/return

Production planning

CollectionList/createRead/update/delete
Tasks/productions/{production_id}/tasks/tasks/{task_id}
Crew/productions/{production_id}/crew/crew/{crew_id}
Calendar events/productions/{production_id}/calendar-events/calendar-events/{event_id}
Call sheets/productions/{production_id}/call-sheets/call-sheets/{call_sheet_id}
Tag notes/productions/{production_id}/tag-notes/tag-notes/{note_id}
Notebooks/productions/{production_id}/notebooks/notebooks/{notebook_id}
Rich notes/notebooks/{notebook_id}/notes/production-notes/{note_id}
Files/productions/{production_id}/files/files/{file_id}
GET/files/{file_id}/content

Budgets

ResourceList/createRead/update/delete
Accounts/productions/{production_id}/accounts/productions/{production_id}/accounts/{account_id}
Budget sheets/productions/{production_id}/budget-sheets/budget-sheets/{budget_sheet_id}
All production rows/productions/{production_id}/budget-rows/budget-rows/{budget_row_id}
Rows in a sheet/budget-sheets/{budget_sheet_id}/rows/budget-rows/{budget_row_id}

Budget-sheet responses include row count, income, expenses, actuals and results. Account-plan entries are organisation-wide but routed through a production so normal budget access is always checked.

Guests

ResourceList/createRead/update/delete
Guest contacts/productions/{production_id}/guests/guests/{guest_id}
Guest bookings/productions/{production_id}/guest-bookings/guest-bookings/{guest_booking_id}

Guest-booking lists accept start, end and status. Acceptance secrets and accepting IP addresses are never exposed.

Call sheet content

ResourceList/createRead/update/delete
People/call-sheets/{call_sheet_id}/people/call-sheets/{call_sheet_id}/people/{item_id}
Equipment/call-sheets/{call_sheet_id}/equipment/call-sheets/{call_sheet_id}/equipment/{item_id}
Vehicles/call-sheets/{call_sheet_id}/vehicles/call-sheets/{call_sheet_id}/vehicles/{item_id}
Schedule/call-sheets/{call_sheet_id}/schedule/call-sheets/{call_sheet_id}/schedule/{item_id}
Contacts/call-sheets/{call_sheet_id}/contacts/call-sheets/{call_sheet_id}/contacts/{item_id}

Each collection supports GET/POST; each item supports GET/PATCH/DELETE. Creates reference resource_id, equipment_id or vehicle_id. Schedule items require start_time and activity; contacts require name.

Common examples

Create a production

curl -X POST \
  -H "Authorization: Bearer $FALCON_OPERATIONS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Summer campaign",
    "code": "SUM-26",
    "type": "commercial",
    "status": "planning",
    "client_name": "Example Client",
    "start_date": "2026-08-01",
    "end_date": "2026-08-14",
    "currency": "DKK",
    "total_budget": 250000
  }' \
  https://operations.wearefalcon.tv/api/v1/workspaces/wsp_.../productions

Create equipment

{
  "name": "Sony FX6",
  "category": "Camera",
  "manufacturer": "Sony",
  "model": "FX6",
  "serial_number": "EXAMPLE-001",
  "status": "available",
  "home_location_id": "loc_...",
  "daily_rate": 1250,
  "currency": "DKK",
  "tags": ["camera", "full-frame"]
}

Equipment, vehicle and space status values are available, in_use, maintenance and retired. Active bookings must be completed or cancelled before deleting an asset.

Create a booking

{
  "title": "Camera package",
  "booked_for_resource_id": "res_...",
  "production_id": "prj_...",
  "starts_at": "2026-08-03T08:00:00+02:00",
  "ends_at": "2026-08-03T18:00:00+02:00",
  "status": "confirmed",
  "purpose": "Location shoot",
  "items": [
    {"asset_type": "equipment", "asset_id": "eqp_..."},
    {"asset_type": "vehicle", "asset_id": "veh_..."}
  ]
}

Detected overlaps are returned in meta.conflicts. Checkout locks ordinary status and manifest changes until all items are returned.

Checkout

{
  "asset_type": "equipment",
  "asset_id": "eqp_...",
  "condition": "Complete and undamaged"
}

Return

{
  "asset_type": "equipment",
  "asset_id": "eqp_...",
  "location_id": "loc_...",
  "condition": "Returned in good condition"
}

Create a task

{
  "title": "Confirm camera crew",
  "description": "Confirm availability and rates",
  "status": "todo",
  "priority": "high",
  "assignee_email": "producer@example.com",
  "due_date": "2026-08-01",
  "tags": ["crew"]
}

Task status is the production's task-column key. Priority values are low, medium, high and urgent.

Assign production crew

{
  "resource_id": "res_...",
  "role": "Director of Photography",
  "start_date": "2026-08-01",
  "end_date": "2026-08-14",
  "daily_rate": 6500
}

Create a budget row

{
  "account_id": "acc_...",
  "description": "Camera crew",
  "quantity": 3,
  "unit": "days",
  "unit_price": 6500,
  "currency": "DKK",
  "approval_status": "draft"
}

row_type is entry, groupHeader, subtotal or textOnly. Approval status is draft, pending, approved or rejected.

Create a guest booking

{
  "guest_id": "gst_...",
  "title": "Guest appearance",
  "starts_at": "2026-08-03T10:00:00+02:00",
  "ends_at": "2026-08-03T11:00:00+02:00",
  "location": "Studio A",
  "live_link": "https://example.com/live"
}

Create a calendar event

{
  "title": "Location scout",
  "start_at": "2026-08-01T09:00:00+02:00",
  "end_at": "2026-08-01T11:00:00+02:00",
  "all_day": false,
  "location": "Example address"
}

Create a call sheet

{
  "title": "Shoot day 1",
  "date": "2026-08-03",
  "call_time": "07:00:00",
  "wrap_time": "18:00:00",
  "location": "Studio A",
  "status": "draft",
  "general_notes": "Bring ID"
}

Call sheet status values are draft, published, archived and cancelled.

Update a rich production note

Rich note content is TipTap JSON. Updates use optimistic concurrency and require the version most recently read:

{
  "expected_version": 3,
  "title": "Updated production note",
  "content": {
    "type": "doc",
    "content": [
      {
        "type": "paragraph",
        "content": [{"type": "text", "text": "Hello"}]
      }
    ]
  },
  "plain_text": "Hello"
}

A stale version returns 409 version_conflict.

Upload a file

curl -X POST \
  -H "Authorization: Bearer $FALCON_OPERATIONS_TOKEN" \
  -F "file=@brief.pdf" \
  -F "description=Client brief" \
  https://operations.wearefalcon.tv/api/v1/productions/prj_.../files

The maximum file size is 20 MB. Executable and active web content types are blocked. The returned content_url also requires the Bearer token.

Validation and conflict protections

  • Location trees reject cycles and duplicate sibling codes. Locations with children or assigned assets cannot be deleted.
  • Bookings validate that resources and assets belong to the same workspace and return overlap details.
  • Booking handover uses database row locks and records checkout/return condition and location history.
  • Rich notes use versions to prevent overwriting another editor's changes.
  • Workspace, module, production-filter and license checks run for every endpoint.
  • Every REST mutation writes actor, token, request ID, action and public resource ID to the Operations audit log.

HTTP status codes

StatusMeaning
200Successful read or update.
201Resource created.
204Resource deleted; no response body.
400Invalid JSON.
401Missing, invalid, expired or revoked token.
403Missing scope or insufficient Falcon access.
404Route or resource not found.
405HTTP method not supported.
409Data, hierarchy, handover or version conflict.
422Validation error.
500Unexpected server error; report the request ID.

Troubleshooting

401 authentication_required

Add the Authorization: Bearer ... header. Do not send tokens in the URL.

401 invalid_token

The token is wrong, expired or revoked, or its Falcon user is no longer active. Create a new token in Operations.

403 scope_required

Create a new token with the named scope. Existing token scopes cannot be broadened after creation.

403 forbidden

The token user lacks the required workspace, production, access-group, module or license permission.

404 not_found

Confirm that the opaque ID uses the correct prefix for the route and that the resource has not been deleted.

409 handover_locked

Return every checked-out item before replacing the manifest, changing ordinary status or deleting the booking.

409 version_conflict

Reload the rich note and retry with its newest version as expected_version.

Browser integrations

The API is designed primarily for server-to-server clients. If a browser sends Origin or Referer, it must match the configured Falcon Operations origin.