Bearer token on every GraphQL call.
All requests go to a single endpoint:
1. Create an API key
API keys are created from the Filed web app, per workspace:- Open the workspace you want to grant access to.
- Go to Plugins and open the API tile, under Prowork.
- Click Create an API Key.
- Choose an Expiry and an Access level (see below).
- Copy the key. It is shown only once, so store it in a secret manager. If you lose it, revoke it and create a new one.
An API key is personal: it authenticates as you, the user who created
it. Every call made with a token minted from the key acts on your behalf and is
limited to what your account is allowed to do in that workspace (the
userToken
from the exchange identifies you). If you leave the workspace or your access
changes, the key’s access changes with you. For a shared or service integration,
create the key from an account you intend to own that integration.Expiry
The key is valid for the window you pick at creation time. After it expires, the exchange step (below) stops working and you must create a new key.2. Scope: one key, one workspace
An API key is scoped to the single workspace it was created in. The access token you get from it can only read and write data in that workspace. To integrate with several workspaces, create one key per workspace.This is different from legacy partner API keys, whose token could reach every
workspace the partner created. New Filed API keys are deliberately
workspace-scoped for tighter, per-workspace access control.
Access levels: read vs read-write
The Access level you pick at creation time is baked into every access token minted from that key:
Pick the narrowest level that fits your integration. If you only pull data, use
Read only so a leaked key can never mutate your workspace.
3. Exchange the API key for an access token
Send your API key as therefreshToken argument to
exchangeSurfaceRefreshTokenForAccessTokens. This is a public mutation: it
is the only call you make without a Bearer token.
Arguments
String!
required
Your API key, exactly as copied from the Filed web app.
Int
Request a shorter access-token lifetime. Values above the maximum for the key’s
surface are clamped to it, so this can only shorten the token, never extend it.
Omit it to get the maximum.
Returns: AccessTokens
String!
A short-lived token identifying you (the user the key belongs to) across
your account, not tied to any one workspace.
String!
A short-lived token that is also you, scoped to the key’s workspace. This
is the token you use for API calls. It carries the key’s access level: a
read_only key mints a read-only workspaceToken.userToken is you account-wide, the workspaceToken is you
within the key’s workspace at the key’s access level.
Both tokens are short-lived: an API key mints tokens that last 3 minutes.
API and MCP keys are capped shorter than Filed’s other surfaces, which run to 30
minutes. When the tokens expire, call the exchange again with the same API key
to mint fresh ones. The API key itself lasts until its expiry.
Example
4. Call the API with the access token
Send theworkspaceToken in the Authorization header on every subsequent
request:
me query. me returns the Me union, which resolves to
WorkspaceUser when you authenticate with a workspaceToken (and to User with
an account-wide userToken). Because it is a union, select fields with an inline
fragment on the type you expect:
cURL
Types
Me
Union of
User (returned with an account-wide userToken) and WorkspaceUser
(returned with a workspace-scoped workspaceToken). Query it with
... on WorkspaceUser { ... } to read workspace fields.ID!
The membership id that links this user to the workspace.
WorkspaceRole!
The user’s role in the workspace:
admin, l1, l2, or l3.Date!
When the user was added to the workspace.
UserShortDetails!
The underlying user account.
emailHash and novuHash back Filed’s own
in-product integrations; integrations can ignore them.Workspace!
The workspace this
workspaceToken is scoped to.Putting it together
A typical integration:- Once, in the web app: create a workspace-scoped API key with the access level you need, and store it as a secret.
- On startup / on 401: exchange the API key for a fresh
workspaceToken. - Per request: send
Authorization: Bearer <workspaceToken>. - When the token expires (3 min): repeat step 2 with the same API key.
Rate limits
API-key traffic is rate limited per key at 120 GraphQL requests per 60 seconds. Over the limit, Filed returns HTTP429 with a Retry-After header
in seconds and a GraphQL error whose extensions.code is RATE_LIMITED. Back
off for the stated interval rather than retrying immediately.
Two things fall outside the limit: the exchange call, which carries no bearer
token, and the resumable upload endpoint, which is not GraphQL. Every call made
with a workspaceToken counts, which is the other reason to cache the token for
its full 3 minutes rather than exchanging per request.
Troubleshooting
exchangeSurfaceRefreshTokenForAccessTokens returns an error
- The API key is wrong, revoked, or past its expiry. Create a new one.
- Confirm you are posting to
https://router.apps.filed.com/graphql.
- The key was created as Read only (
read_only), and the mutation came back withextensions.codeset toFORBIDDEN. Create a Read and write key to allow mutations.
- The
workspaceTokenexpired. Re-exchange the API key for a new one.
429
- You crossed the rate limit. Back off for the number of seconds in the
Retry-Afterheader. See Rate limits.