Get started
Quickstart
Create an API key in the API and MCP section of the Filmo settings, then call GET /api. The response tells you the timezone, currency, add-ons and scopes to build with.
Requirements
Link to this section: Requirements- A Filmo account whose environment has the API and MCP switched on by Filmo; an administrator of the account cannot switch it on. The API and MCP are included in any paid plan and are not an add-on, and a free trial (14 days, no card) can create keys too.
- An administrator of the account to create the key. If that is not you, read the next section first.
- The add-ons for the resources you plan to use. A free trial unlocks all of them, and when it ends the endpoints behind an add-on answer 402
addon_required. - For the examples: cURL, Windows PowerShell 5.1 or later, Node 22 or later, or Python 3 with
requests.
The base URL is https://. Plans and add-ons explains what each add-on opens.
Not an admin?
Link to this section: Not an admin?Only an administrator can create a key, and the key acts as that person (Permissions). Ask an administrator for a key and tell them:
- The exact scopes your integration needs. Always include
account:read: the first call needs it, and without it you get 403insufficient_scope. - To name the key after the integration, so it can be found and revoked later.
- To send you the key through a shared secrets manager, never by email or chat. It is shown once and gives programmatic access to the company's data.
Who owns a key and what happens when that person leaves is explained in Authentication.
Create a key
Link to this section: Create a keyOpen the API and MCP settings
In the Filmo app, as an administrator, open the section of the settings for the API and MCP. In the Spanish interface it reads Ajustes → API y MCP.
Add a key
Give it a name that says what it is for and choose its scopes. Include
account:read, and add only what the integration needs. Set an expiry date if the form offers one and you rotate keys on a schedule; a key without a date never expires.Copy the key now
The key starts with
fk_live_and is shown only once; Filmo keeps only a hash of it. Store it in a secrets manager or an environment variable, not in your code or your repository.
For the same steps without the API vocabulary, see Generate an API key in the help center.
Make the first call
Link to this section: Make the first callSet the key in an environment variable and call GET /api. The examples read FILMO_API_KEY and, if set, FILMO_BASE_URL; the default base URL is https://.
# Paste the key when asked; it stays out of your shell history. Works in bash and zsh.
printf 'Filmo API key: '; stty -echo; read -r FILMO_API_KEY; stty echo; echo; export FILMO_API_KEY
FILMO_BASE_URL="${FILMO_BASE_URL:-https://app.filmo.io}"
curl -sS "$FILMO_BASE_URL/api/v1/account" \
-H "Authorization: Bearer $FILMO_API_KEY" \
-H "Accept-Language: en-US"# Windows PowerShell 5.1 and PowerShell 7. Paste the key when asked.
$secure = Read-Host "Filmo API key" -AsSecureString
$env:FILMO_API_KEY = [System.Net.NetworkCredential]::new("", $secure).Password
$base = if ($env:FILMO_BASE_URL) { $env:FILMO_BASE_URL } else { "https://app.filmo.io" }
try {
$response = Invoke-RestMethod -Uri "$base/api/v1/account" `
-Headers @{ Authorization = "Bearer $env:FILMO_API_KEY"; "Accept-Language" = "en-US" }
$response.data | ConvertTo-Json -Depth 5
} catch {
# The body of the problem is in ErrorDetails; the status is in the exception.
Write-Error $_.ErrorDetails.Message
exit 1
}
# Alternative with curl.exe (the .exe matters: plain curl is an alias in Windows PowerShell 5.1):
# curl.exe -sS "$base/api/v1/account" -H "Authorization: Bearer $env:FILMO_API_KEY"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}`,
"Accept-Language": "en-US",
},
});
// Check the status before parsing: a platform error may not be JSON.
if (!res.ok) {
console.error(res.status, res.headers.get("content-type"), await res.text());
process.exit(1);
}
const { data } = await res.json();
console.log(data.timezone, data.currency, data.addons, data.apiKey.scopes);import os
import sys
import requests
base = os.environ.get("FILMO_BASE_URL", "https://app.filmo.io")
res = requests.get(
f"{base}/api/v1/account",
headers={"Authorization": f"Bearer {os.environ['FILMO_API_KEY']}", "Accept-Language": "en-US"},
timeout=30,
)
# Check the status before parsing: a platform error may not be JSON.
if not res.ok:
print(res.status_code, res.headers.get("content-type"), res.text, file=sys.stderr)
sys.exit(1)
account = res.json()["data"]
print(account["timezone"], account["currency"], account["addons"], account["apiKey"]["scopes"])The cURL tab is for macOS and Linux shells. On Windows PowerShell 5.1, curl is an alias of Invoke-WebRequest and the -H flag fails: use Invoke-RestMethod as above, or call curl.. In Command Prompt, variables are written %FILMO_API_KEY%, not $FILMO_API_KEY:
rem Command Prompt (cmd.exe): variables are %NAME%, not $NAME.
rem cmd.exe shows the key while you type it: use PowerShell if anyone can see your screen.
set /p FILMO_API_KEY=Filmo API key:
curl.exe -sS "https://app.filmo.io/api/v1/account" -H "Authorization: Bearer %FILMO_API_KEY%"A successful call returns 200 with the account inside the usual data envelope (the values below are fictitious):
{
"data": {
"name": "Acme Rentals",
"timezone": "Europe/Madrid",
"currency": "EUR",
"country": "ES",
"language": "en-US",
"addons": ["crm"],
"trial": { "active": false, "endsAt": null },
"apiKey": {
"id": "example-key-id",
"name": "Inventory sync",
"scopes": ["account:read", "items:read", "orders:read"]
},
"rateLimits": {
"global": { "perMinute": 120 },
"availability": { "perMinute": 30 }
},
"api": {
"version": "1.0.0",
"docsUrl": "https://docs.filmo.io"
}
}
}Read the response
Link to this section: Read the response| Field | What to do with it |
|---|---|
timezone | The business timezone. A bare day such as 2026-10-17 in a filter is read in it. When you write, send instants with an offset. |
currency | The currency of the account. Amounts are decimal strings with two decimals, and a document may carry its own currency. |
language | The default language of error messages for this key, unless Accept-Language says otherwise. Never branch on message text. |
addons | The add-ons the account has today. A resource behind an add-on that is not listed answers 402. While the trial is active every add-on is unlocked, so do not decide from this list until the trial has ended. |
trial | While active is true every add-on is unlocked; endsAt is when that stops. |
apiKey | The key that made the call: its name and its scopes. The secret is never returned. |
rateLimits | Requests per minute: the global quota and the separate quota of the availability queries. |
api | The version of the contract this account is served with, and where its documentation lives. |
If the first call fails
Link to this section: If the first call failsFind the symptom, then the cause. Errors are RFC 9457 problems: branch on code, never on detail. Quote requestId to support (Support).
| Symptom | Cause and fix | Error |
|---|---|---|
| 401 and the detail says the Authorization header is missing or malformed | The header must be exactly Authorization: Bearer <key>, with the word Bearer and a space. A bare key, Token or Basic is rejected. | unauthorized |
| 401 for a key that was working | The key is wrong, was revoked or has expired. Check how it reached your shell, and issue a new one if needed. | api_key_invalid, api_key_revoked, api_key_expired |
| 404, or a response that is not a Filmo problem body | Every path starts with /api, not /v1. Use https://. | None |
| 401 after the key owner changes role or leaves | The person who created the key is no longer an administrator, or is deactivated. The key is fine; reissue it from an account that is still an administrator. | api_key_owner_not_admin, api_key_owner_inactive |
| 403 on the first call | The key does not carry account:read. requiredScope in the body names it. Create a key that includes it. | insufficient_scope |
| 400 on a later write that carries a date | A date and time in a write needs an offset: 2026-10-17T09:00:00+02:00, not 2026-10-17T09:00:00. Only a field that is a plain date, such as invoiceDate in PUT /api, takes a bare day. errors[]. points at the field. | validation_error |
| 402 instead of 403 | A 402 is about an add-on: the account does not have the add-on of the module that resource belongs to, and no role bypasses it. A 403 is about the key or its owner. See Permissions. | addon_required, forbidden |
| The browser blocks the call (CORS) | Do not call the API from a web page. In production the API allows cross-origin browser calls only from https://docs.filmo.io, so a browser blocks the call from any other origin; and keys are for servers, because a key in a browser is exposed. | None: the browser stops it |
The detail is in Spanish | Without Accept-Language, a 401 for a missing or unknown key comes back in Spanish, because there is no owner to ask; every other error uses the preferred language of the key owner. Always send Accept-Language: en-US (es-ES and en-US are guaranteed), and do not base logic on detail. | Any |
The response is not application, for example a 413 or a 504 | The platform in front of the API answered, not the API. Check the status and Content-Type before parsing; do not assume a JSON body. Retry a 504 after a pause. | Not a Filmo code. Server faults of the API are internal_error and service_unavailable |
PowerShell 5.1: curl fails on -H | curl is an alias of Invoke-WebRequest. Use Invoke-RestMethod, or curl.. | None: the shell fails first |
| cmd: the key is not sent | $FILMO_API_KEY is not expanded in Command Prompt, so the header carries that literal text and the key is rejected. Write %FILMO_API_KEY%. | api_key_invalid |
In a cURL command, Idempotency-Key goes out empty | uuidgen does not exist on Windows or on minimal Debian and Alpine images, so $(uuidgen) in a -H option expands to nothing. Generate the id in your language: crypto. in Node, uuid. in Python, [guid]::NewGuid() in PowerShell. | None: the retry is unprotected |
Next steps
Link to this section: Next steps- Capabilities and limits: what v1 covers, its hard limits and what it does not do.
- Syncing data: keep your system in step with Filmo by polling for changes.
- Going live: the checklist before production.
- MCP quickstart: give an AI assistant the same access.
Related pages
Link to this section: Related pagesGuides
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.
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.Introduction
MCP quickstart
Connect one assistant, check it with a read tool and choose the scopes it needs.
Further reading
Capabilities and limits of v1
The API covers most day-to-day work on orders, contacts, items, invoices and the schedule, and leaves a short list of things to the app. Check it here before you design an integration around a feature.
Was this page helpful?