Guides

Multi-account integrations

Give each customer account its own credential, store it with that account's timezone and currency, and treat a failing credential as the state of one connection, not of your whole product. OAuth is available for a server you run, and API keys are simpler for server-to-server work.

This guide is for teams that build a product, such as a CRM, an accounting package, a booking site or an inventory tool, that connects to many rental companies. That is the case the API was designed for: third-party integrations. If you integrate with one company's account, the quickstart and the sync guide are enough.

A credential belongs to one Filmo subscription, so one credential can never serve two customers. You can obtain it in two ways.

API keyOAuth connection
Who creates itAn administrator of the customer, in the API and MCP settings of the app (Ajustes → API y MCP).An administrator of the customer, on the consent screen. That is where the subscription is chosen. Only read permissions start selected; write permissions, workflows:run and ai:ask start unselected even if you ask for them, and the administrator turns on the ones they accept.
LifetimeUntil it is revoked, or until the expiry you set when you created it. It has no expiry by default.The access token lasts 1 hour. The refresh token lasts 30 days, counted again at every rotation, so a connection that is refreshed at least every 30 days lives on.
PermissionsThe scopes chosen when it was created.The scopes actually granted, which may differ from the ones requested (fewer, or extra ones the administrator ticked).
RevocationIn the same settings (Ajustes → API y MCP). It stops working at once.The same screen, where it appears as a single connected integration. The access token stops working at once and the refresh token can no longer be exchanged.
FitSimplest for server-to-server integrations: one secret per customer, nothing to refresh.Works for REST from your server, at the price of a refresh cycle and a consent by an administrator of each account.

The token OAuth issues is a short-lived API key that works on the whole REST API and on MCP, and it travels the same way, as a Bearer token. A third-party server can use it today: it registers as a public client, sends the administrator through the authorization code flow with PKCE, and exchanges the code for tokens. OAuth is viable now, and a key is simpler when no person is in front of the flow. See OAuth for the flow.

  • There is no client_credentials grant, no confidential client and no client secret. Your client is public: it registers dynamically and authenticates with PKCE alone.
  • Every connection needs an administrator of that account to consent. You cannot connect an account without one.
  • A grant covers one subscription, which the administrator chooses while consenting, and the granted scopes may differ from the ones you requested (fewer, or extra ones the administrator ticked). A customer with several billing accounts needs one grant, or one key, for each of them.
  • A subscription can have 50 keys that are not revoked (expired ones count, and so do OAuth connections); the limit blocks creating a new key by hand.

Keep recommending one key or one connection per customer, and never share a credential between two accounts or two environments.

The first call of any integration is GET /api/v1/account, with the scope account:read. Call it when a customer connects and keep what it returns.

StoreWhy
The credential, encryptedA key, or the access and refresh tokens of an OAuth connection. It is shown only once.
timezoneBare days in filters are read in this timezone, and you need it to show times to people the way the customer sees them.
currencyThe account's currency. A document may carry its own.
apiKeyThe key's id, name and granted scopes. Compare the scopes with the ones you need whenever a call answers 403.
addonsA resource behind an add-on that is not listed answers 402.
The state of the connectionActive, or needs attention, with the time of the last good call and the last X-Request-Id you saw.
One watermark per listSee the sync guide. Watermarks belong to the customer, not to your product.

What a credential can see depends on how Filmo models each resource (Accounts and tenancy). Two rules matter for an integration.

SemanticsResourcesWhat the credential sees
Inherited from the parent accountContacts, projects, tags and custom fields, and reading an order by id.A billing account also sees these resources of its parent account. A full account, or a subscription outside any organization, sees its own.
Strict subscription equalityEverything else, including items, spaces, invoices, quotes, tasks, vehicles, staff, subrents, purchase orders, contracts, the order list and availability.Exactly the subscription that owns the credential.

Nothing widens between sibling billing accounts, nor from a parent to its billing accounts, and no operation crosses data between organizations. So, to read the orders and invoices of every billing account of one organization, connect each of them. When you merge their data, deduplicate the inherited resources by id: the same contact appears through every billing account that inherits it.

Each key has 120 requests per minute, and the three availability queries share a further 30 per minute on the same key. The limits are the same for every plan (Rate limits). A credential is the unit of the limit, so give each customer its own queue, read RateLimit-Remaining and RateLimit-Reset to pace it, and wait Retry-After seconds after a 429. Workers that serve the same customer share one budget.

OAuth has its own limits, counted per IP address and not per credential. Registering a client allows 5 requests per minute per IP, and the token endpoint 120 per minute per IP, so the refreshes of all your customers share that budget when they leave from the same server. A 429 from an OAuth endpoint carries Retry-After: wait that long, and decide by the status and the header, not by the body, because the body does not always name the limit.

OAuth: refreshing without breaking the connection

Link to this section: OAuth: refreshing without breaking the connection

This section applies if you use OAuth connections. With API keys there is nothing to refresh.

The access token expires in 1 hour and the refresh token rotates on every use: each exchange returns a new refresh token, and the previous access token stops working at once. If a worker presents a refresh token that was already rotated, Filmo answers with the same pair when the request comes from the same client within 10 seconds of the rotation. After that window, reusing it revokes the whole chain, the access token and every refresh token, and answers invalid_grant. The customer then has to consent again. Two workers that refresh at the same moment usually receive the same pair, but a worker that arrives later than 10 seconds destroys the connection for everyone, so serialize the refresh anyway.

OAuth endpoints answer in the flat OAuth format, { "error", "error_description" }, not in the problem format of the rest of the API. The error_description is in Spanish: branch on error and show your own text.

  1. Serialize the refresh per customer

    Take a lock for that customer's connection around the whole refresh: a database row lock, an advisory lock, or a lock with an expiry in a shared store. Never refresh outside it.

  2. Read the stored tokens after you get the lock

    Another worker may have refreshed while you waited. If the stored access token is still valid, use it and release the lock.

  3. Refresh with the stored refresh token

    Call POST /api/v1/oauth/token with grant_type=refresh_token, the refresh_token and your client_id. The response carries a new refresh_token, valid for another 30 days.

  4. Persist both new tokens before anything else

    Write the new access token and the new refresh token to storage before you use the access token and before you release the lock. If you lose the new refresh token, the connection is lost.

  5. Refresh before expiry, not on a 401

    Refresh a few minutes before the hour is up, so that request threads rarely race for the lock.

Treat invalid_grant as final: the refresh token is expired, revoked or already used, or the administrator who consented is no longer an administrator. Do not retry it. Mark the connection as needing attention and ask the customer's administrator to consent again.

Handle each failure as the state of one connection: stop calling with that credential, keep the watermarks, tell the customer's administrator, and resume after they reconnect. Do not retry in a loop.

ResponseMeaningWhat to do
401 api_key_invalid, api_key_revoked, api_key_expiredThe key is not recognised (a key copied wrongly or truncated lands here too: check your value first), was revoked or has expired.Check that the value you send is complete. If it is, ask the administrator for a new key, or to consent again. For an OAuth connection, a 401 api_key_expired means the access token ran out: refresh it before you conclude that anything is wrong.
401 api_key_owner_inactive, api_key_owner_not_adminThe key is fine; the person who owns it left the account, was deactivated, or stopped being an administrator.Ask an administrator who is still one to reissue the key, or to consent again. The same applies to OAuth connections.
401 unauthorizedThe Authorization: Bearer header is missing.Fix your request. Nothing is wrong on the customer's side.
403 insufficient_scopeThe credential lacks the scope named in requiredScope.Ask for a new key or a new consent with that scope.
403 forbiddenThe owner of the credential lacks a permission that the operation requires.An administrator of the account grants it.
402 addon_requiredThe customer's account has not contracted the add-on named in requiredAddon.Turn the feature off for that customer and say why.
429 rate_limitedThe key's quota ran out.Wait Retry-After seconds (the problem body repeats the value in retryAfter).

Handover checklist for the customer's administrator

Link to this section: Handover checklist for the customer's administrator

Give this list to the administrator who connects your product. Fill in the scopes from your own needs, and ask for no more.

  1. Choose a dedicated owner

    A key acts as the administrator who creates it, and what it writes is attributed to that person. It hangs from that administrator, who already has a seat in the account, and it stops working if that person leaves or stops being an administrator. Create it from an administrator account that will last, not from a person who may move on.

  2. Open the API and MCP settings

    In the app it is Ajustes → API y MCP. Only administrators can create keys.

  3. Create one key for the integration

    Name it after your product and give it only the scopes you list, for example account:read plus the read and write scopes of the resources you sync. The scopes are in the scopes reference.

  4. Hand it over once, through a secure channel

    The key is shown only once. Receive it in your onboarding form or a shared secrets manager, never by email or chat.

  5. Explain revocation

    Revoking the key in the same settings cuts access at once. Tell the administrator what stops working when they do, and what to do if the owner of the key leaves.

Filmo offers no sandbox and no test key, and this guide describes no partner or developer account type. Develop and run your tests against a separate Filmo account that holds fictitious data (contacts at example.com, made-up item names), with its own key stored apart from any customer's. A free trial of 14 days, with no card, can serve for that. Never develop against a customer's account. Writes fire the account's event workflows, so check which are active before you write; see Testing and the sync guide.

If you are building a product for many Filmo customers and want to talk to Filmo about it, see Support.

  • 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.

  • 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

    Scopes

    A key carries scopes; each operation requires exactly one. Grant the fewest you need.

  • Guides

    Rate limits

    Each API key has 120 requests per minute, and the three availability checks share their own quota of 30 per minute. Past a limit the API answers 429 with Retry-After.

  • Guides

    Syncing data

    Filmo v1 does not send webhooks, so you keep another system in step by polling: read what changed in half-open time windows, and run a separate sweep to find what was deleted. Do not follow the pagination cursor to decide what changed or what disappeared.

  • Guides

    Testing your integration

    Start with a read-only key, check the account's automations before the first write, and keep irreversible operations out of any account that holds real data.

  • 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.

  • Core concepts

    Accounts and tenancy

    A key is bound to one subscription. Most resources are limited to exactly that subscription; contacts, projects, tags and custom fields are also visible from a billing account's parent.