Guides
Authentication
Every operation requires an API key sent as a bearer token. Only an administrator can create a key, and the key acts as that administrator, so decide who owns it before you create it.
Send the key
Link to this section: Send the keyPut the key in the Authorization header of every request, as a bearer token. Every key starts with fk_live_: there is a single prefix, and there are no separate test or sandbox keys, so every key works on the live data of its account. The documentation is public; what is restricted is the credential.
GET /api/v1/account HTTP/1.1
Host: app.filmo.io
Authorization: Bearer <your API key>To check what a key can do, call GET /api. It returns the key that made the request, with its name and scopes but never its secret (apiKey).
# The scopes of the key are in data.apiKey.scopes.
curl -sS "${FILMO_BASE_URL:-https://app.filmo.io}/api/v1/account" \
-H "Authorization: Bearer $FILMO_API_KEY" | jq '.data.apiKey'const base = process.env.FILMO_BASE_URL ?? "https://app.filmo.io";
const res = await fetch(base + "/api/v1/account", {
headers: { Authorization: `Bearer ${process.env.FILMO_API_KEY}` },
});
if (!res.ok) {
// 401 and 403 come back as application/problem+json: branch on `code`.
const problem = await res.json();
throw new Error(res.status + " " + problem.code + " (request " + problem.requestId + ")");
}
const { data } = await res.json();
console.log(data.apiKey.name, data.apiKey.scopes);import os
import requests
base = os.environ.get("FILMO_BASE_URL", "https://app.filmo.io")
res = requests.get(
base + "/api/v1/account",
headers={"Authorization": f"Bearer {os.environ['FILMO_API_KEY']}"},
timeout=30,
)
if not res.ok:
# 401 and 403 come back as application/problem+json: branch on "code".
problem = res.json()
raise SystemExit(f"{res.status_code} {problem['code']} (request {problem['requestId']})")
key = res.json()["data"]["apiKey"]
print(key["name"], key["scopes"])Create a key
Link to this section: Create a keySign in as an administrator
Only administrators of the account can create keys, by hand or through OAuth.
Open the API and MCP settings
In the Spanish interface the section is called Ajustes → API y MCP.
Create the key and name it after the integration
Use one key per integration, so you can revoke one without touching the others.
Choose the scopes
Tick only the permissions the integration calls. The scopes of a key cannot be edited afterwards: to change them, create a new key and revoke the old one. See Scopes.
Set an expiry date, if you want one
The date is optional and must be in the future. A key without a date does not expire, and no key expires for lack of use.
Copy the key and store it
Filmo shows the key once and stores only a hash of it, so it cannot show it again. Put it in a secret manager or an environment variable before you close the dialog.
The key is shown only once and amounts to programmatic access to your company's data. If you lose it, create a new key and revoke the old one.
The Help Center has the same procedure with screens: Generate an API key.
Who owns the key
Link to this section: Who owns the keyA key hangs from a real administrator of the account, the one who created it, and everything it writes is attributed to that administrator. The same holds for each OAuth connection.
Filmo checks that condition on every request, not only when the key is created. If the person who created the key leaves the account or is deactivated, the key answers 401 api_key_owner_inactive. If they stop being an administrator, it answers 401 api_key_owner_not_admin. The key itself is fine: what changed is the role of its owner, and the fix is to reissue the key from an account that is still an administrator.
Create production keys from a dedicated administrator account
Link to this section: Create production keys from a dedicated administrator accountDo not create production keys from the account of a person who may leave or change role. Create a dedicated, long-lived administrator account for integrations, name it after what it is for, and create the keys from it. There is no service or bot user today: the key owner is a real user. The key itself does not take a seat, but the administrator account you create it from is a user like any other and does, so budget for that account.
Contractors and agencies
Link to this section: Contractors and agenciesA developer or an agency working for a rental company is not an administrator of its account and cannot create a key. The administrator of the rental company creates the key with only the scopes the work needs and hands it over through a shared secret manager, never by email or chat. The contractor does not need an administrator login. When the work ends, the administrator revokes the key.
Revoke or rotate a key
Link to this section: Revoke or rotate a keyRevoke a key in the API and MCP section of the settings (*Ajustes → API y MCP*). A revoked key answers 401 api_key_revoked. A connection made through OAuth appears there labeled as a connected integration, and revoking it cuts off access immediately.
There is no rotation command. Several keys can be active at once, and that overlap is how you rotate a key without downtime:
Create a new key
Same name pattern and same scopes.
Deploy it
Update the secret your integration reads and restart it.
Check the traffic
Confirm the integration calls succeed with the new key.
Revoke the old key
A subscription can have up to 50 keys that are not revoked (an expired key still counts). OAuth connections count in that total, but only creating a key by hand is refused at the limit. Revoke the ones you no longer use.
Authentication errors
Link to this section: Authentication errorsA request without a usable key is answered with 401 and a problem document. Branch on code. Filmo checks a key in this order: it is recognized, then not revoked, then not expired, then its owner is still an active administrator; the first check that fails decides the code. A 401 and a 403 insufficient_scope do not consume rate-limit quota; every other response of an authenticated key does.
| Status | Error | Meaning | What to do |
|---|---|---|---|
| 401 | unauthorized | The request has no valid Authorization bearer header. | Send Authorization: Bearer <key>. |
| 401 | api_key_invalid | The key is not recognized. | Check that the whole key was copied; create a new one if in doubt. |
| 401 | api_key_revoked | The key was revoked. | Create a new key. |
| 401 | api_key_expired | The key has expired. | Create a new key. |
| 401 | api_key_owner_inactive | The administrator who created the key left the account or was deactivated. | Reissue the key from an account that is still an administrator. |
| 401 | api_key_owner_not_admin | The owner of the key is no longer an administrator. | Reissue the key from an administrator account. |
A 403 is a different problem: the key authenticated but may not do this. insufficient_scope is about the key, forbidden about its owner and addon_required (402) about the add-on of a module. Errors tells them apart. Every error body carries a requestId; quote it when you contact support.
Keep the key safe
Link to this section: Keep the key safe- Call the API from a server. Never put a key in browser code, a mobile app or a public repository: anyone who has it has programmatic access to the company's data. In production the API accepts cross-origin browser requests only from
https://, and the OAuth and MCP endpoints send no CORS headers at all, so a page on any other origin cannot call it anyway.docs. filmo. io - Read the key from an environment variable or a secret manager, as the examples do with
FILMO_API_KEY. - Do not write the
Authorizationheader to logs. - Give each integration its own key with the narrowest scopes it needs.
- Alert on 401
api_key_owner_inactiveandapi_key_owner_not_admin: they mean an integration is about to stop. See Going live.
How scopes work
Link to this section: How scopes workEach key carries a set of scopes, chosen when an administrator creates it in the API and MCP section of the settings (*Ajustes → API y MCP*). Each operation requires exactly one scope, shown on its page and in the OpenAPI file as x-required-scope. There are 59 scopes in all.
orders:readlets a key read orders.orders:writelets it create, change and act on them. Do not assume that write includes read: a key that writes orders and reads them back needs both.- A scope covers a resource, not a single operation. One write scope covers every create, update, delete and action on that resource.
- Some scopes have no write twin, such as
account:read,users:readandschedule:read. - Two scopes are special.
workflows:runruns a workflow.ai:askasks the AI about your data and spends AI credits.
Scopes bound which operations a key may call. The data it sees is bounded separately by the account (see Accounts and tenancy), and some operations also need an add-on on the account. Over MCP the same scopes apply, and a key sees only the tools it can call.
When a call is refused: 403 insufficient_scope
Link to this section: When a call is refused: 403 insufficient_scopeA key without the scope an operation needs gets 403 insufficient_scope. The body names the missing scope in requiredScope. Fix it by issuing a key that has that scope.
{
"type": "https://docs.filmo.io/errors/insufficient_scope",
"title": "Insufficient scope",
"status": 403,
"code": "insufficient_scope",
"detail": "The API key does not have the required scope (orders:write)",
"requiredScope": "orders:write",
"requestId": "req_5f1c2f4e3a5b4f6d8e7a0b1c2d3e4f5a"
}Two other refusals look similar and have different fixes.
| Response | About | Fix |
|---|---|---|
403 insufficient_scope | The key. It lacks the scope. | Issue a key with the scope in requiredScope. |
403 forbidden | The owner of the key. The key is right, but its owner lacks the module, organization or administrator permission the operation needs. | An administrator of the account grants the permission. |
402 addon_required | The plan. The account has not contracted, or has let expire, the add-on of that module. | Contract the add-on named in requiredAddon. No role bypasses it. |
The help center explains the permissions in the app: API scopes and permissions and Roles and permissions.
Least privilege
Link to this section: Least privilege- One key per integration, so you can revoke one without touching the others.
- Start with the
:readscopes. Add a write scope only for the resource you write. - Always include
account:read.GET /apiis the first call of any integration: it returns the scopes of the key, the add-ons of the account and the version of the contract./v1 /account - Leave
ai:askandworkflows:runout unless the integration really uses them. - Check what a key can really do by calling
GET /apiwith it. A key made through OAuth can end up with different scopes than requested (fewer, or extra ones the administrator ticked)./v1 /account
curl -sS "${FILMO_BASE_URL:-https://app.filmo.io}/api/v1/account" \
-H "Authorization: Bearer $FILMO_API_KEY"Recipes by integration type
Link to this section: Recipes by integration typeThese are starting points. Remove what your integration does not use; add what a particular call asks for in requiredScope.
CRM contact sync
Link to this section: CRM contact syncaccount:readcontacts:readcontacts:write- Optional:
custom-fields:readto map custom fields, andtags:readandtags:writeto tag what you import.
Web form that creates an opportunity
Link to this section: Web form that creates an opportunityaccount:readcontacts:readto look the person upcontacts:writeto create themcrm:readto read the pipelinescrm:writeto create the opportunity- The CRM operations also need the CRM add-on on the account.
Availability and reservations on a booking site
Link to this section: Availability and reservations on a booking siteaccount:readavailability:readitems:readcontacts:readandcontacts:writeorders:readandorders:writeto create and reserve the order
Inventory sync
Link to this section: Inventory syncaccount:readitems:read, which also covers serialized items- Optional:
spaces:readfor warehouses anditems:writeonly if you write stock data back
Schedule sync
Link to this section: Schedule syncaccount:readschedule:read- Optional:
tasks:read,planner:read,staff:readandvehicles:readif you also need tasks, assignable resources, staff or vehicles
Invoices to accounting
Link to this section: Invoices to accountingaccount:readinvoices:read, which covers invoices, their lines and credit notestreasury:readfor paymentscontacts:readfor the customer's tax identifierinvoices:writeonly if you mirror invoices issued by your ERP withPUT /api/v1 /invoices /external /{originSystem} /{originExternalId}
Every scope, with the operations that need it, is on the scopes page.
Related pages
Link to this section: Related pagesGuides
Scopes
A key carries scopes; each operation requires exactly one. Grant the fewest you need.
Guides
OAuth
Filmo implements OAuth 2.1 for public clients: authorization code with PKCE, no client secret. The token it issues is an API key of kind OAuth, so it works on the whole REST API and on MCP, with the scopes the administrator granted.
Guides
Errors
Errors are RFC 9457 problem documents. Branch on the stable
code, never on the text, and use the retry table to decide whether to try again.Guides
Going live checklist
Go through these eight checks before your integration runs against production data. Each one points to the guide that explains it.
Was this page helpful?