Acting on behalf
Drive any child company from a single master API key with the X-Active-Profile header — profile resolution, the ownership guard, and how scopes stay fixed.
Once you have managed companies under your master tenant,
there are two ways to act on one of them. You can mint a
child API key bound to it — useful when you want a
credential scoped to a single company. Or you can keep using your master key
and pick the target company per request with the X-Active-Profile header. One
master key then operates on any company in your tree, without re-authenticating
or juggling a key per NIF. This page covers the header.
Set the header to the public id (UUID v7) of the child company you want to act
on. It works on any endpoint — invoices, clients, series, and the rest:
curl https://api.factuarea.com/v1/invoices \
-H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z" \
-H "X-Active-Profile: 01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c"When the header is present and the company is yours, the whole request runs
against that child company's data: every read is filtered to it and every write
lands on it. The request is resolved to the child company's company_id before
rate limiting and idempotency, so each company has its own buckets.
The header is optional and additive. Omit it and the request operates on the company your key belongs to — exactly as before. Existing integrations keep working unchanged.
The header never widens your key. Its scopes, tier and environment
carry over untouched: a master key holding only invoices:read that targets a
child company still cannot POST /v1/invoices there (403 insufficient_scope),
and a fact_test_ key stays in the sandbox regardless of the active profile.
Switching profile changes which company you act on, never what you are
allowed to do. The child company inherits the master's plan and add-ons.
Resolution and errors
X-Active-Profile resolves the active company before any handler runs:
| Header | Outcome |
|---|---|
| Absent or empty | The request operates on the company the key belongs to (no-op). |
Your own master company's id | Allowed — equivalent to omitting the header. |
A child company you own, active | The request operates on that child company. |
A child company you own, but inactive | 403 company_inactive — reactivate it first. |
| Not a valid UUID v7 | 400 parameter_invalid_uuid, with param: "X-Active-Profile". |
| A company you do not own (another tree, or non-existent) | 404 profile_not_found. |
The 404 is indistinguishable whether the company belongs to another master
or does not exist at all — the API never reveals that a company outside your tree
exists:
{
"error": {
"type": "not_found_error",
"code": "profile_not_found",
"message": "El perfil de empresa indicado no existe o no pertenece a tu cuenta.",
"param": "X-Active-Profile"
}
}The 403 is different: the company is yours, so revealing that it is
deactivated is legitimate — it is the signal to
reactivate it before operating:
{
"error": {
"type": "authorization_error",
"code": "company_inactive",
"message": "Esta empresa está desactivada. Actívala para operar.",
"param": "X-Active-Profile"
}
}Which one should you use?
X-Active-Profile and child API keys solve different
needs and coexist:
- Use a child key to hand a narrowly scoped credential to an integration tied to one company — the credential itself is bound to that company.
- Use the header to drive many companies from a single master key — one credential, target chosen per request.
The header only switches the active company. It never changes the key's scopes,
and cross-master isolation is enforced the same way as for
managing the companies: a company outside your tree is
never observable, returning 404 rather than 403.