Before you start
Filed registers each partner by hand. Contact Filed to receive:
You supply your redirect URI during registration. Filed matches it exactly,
so a trailing slash or an extra query parameter is rejected. Register every
environment you need (production, staging) as a separate URI.
Your customers must already be Filed customers. Filed does not offer self-serve
signup, so a workspace is created under contract by the Filed team. Signing a
customer up in your product does not create a Filed account for them.
Endpoints
Filed publishes
RFC 8414 metadata, so most OAuth
libraries can configure themselves:
cURL
Scopes
Request only what you use. Your customer sees this list on the consent screen in the wording below, so an unnecessary scope is a reason for them to decline.
Omit the
scope parameter to request everything you are registered for.
Scopes are recorded on the grant and shown to the customer, but Filed does not
yet enforce them field by field. Today a token’s real limit is the workspace it
belongs to, and whether the grant included any write scope at all. Treat scopes
as a contract you keep, not a boundary Filed enforces for you.
Connect a customer
1. Send the customer to Filed
Generate a PKCE verifier and challenge, store the verifier against the user’s session, and redirect their browser to the authorization endpoint.string
required
The identifier Filed issued you.
string
required
Must match one of your registered URIs exactly.
string
required
Always
code.string
required
Base64url SHA-256 of your verifier.
string
required
Always
S256. Filed rejects plain.string
Space-delimited. Omit to request every scope you are registered for.
string
Returned to you unchanged. Use it to defend against CSRF.
2. The customer approves
Filed asks them to sign in, choose which of their workspaces to connect, and review what you are asking for. The grant covers that one workspace: your token cannot reach the customer’s other workspaces. Only an opaque handle for the request travels in the browser. Yourclient_id
and the requested scopes stay on Filed’s server, so nothing the customer can
edit in the URL bar changes what the grant permits.
3. Receive the code
Filed redirects back to yourredirect_uri:
state matches what you stored. The code is single use and expires after
60 seconds, so exchange it immediately.
4. Exchange the code for tokens
Call the token endpoint from your backend. Authenticate with HTTP Basic, sending yourclient_id as the username and your client_secret as the
password. This is the client_secret_basic method.
cURL
string
A Filed workspace token. Send it as a bearer token to the Filed API.
string
Always
Bearer.number
Seconds until the access token expires. Always
180.string
Store this against the customer. It is the credential that represents the
grant, and stays valid as long as it is used at least once every 90 days.
string
Space-delimited scopes the customer approved. Returned on this exchange only.
string
The workspace the grant is pinned to. Returned on this exchange only, because it
never changes for the life of the grant.
string
Display name of that workspace, so you can show the customer what they connected.
Returned on this exchange only.
5. Call the Filed API
cURL
Pushing documents
Documents go in the same way as any other integration — stage the files, then calladdClientDocuments — with one extra
step the first time you push for a client.
Link the client to your connection first. addClientDocuments takes a Filed
clientId, and the push is refused with FAILED_PRECONDITION until a link
exists between your connection and that client:
externalId is your identifier for the client. Filed cannot create the link
for you because only you know that value, and it is what lets you find the same
client again later.
The link is also how Filed attributes what you push. A document filed under your
connection’s link is traceable back to your product; without one it would be
indistinguishable from a document the customer uploaded in Filed themselves —
the access token identifies the customer who approved your grant, not whoever
acted in your product.
Creating the client yourself? Pass sourceExternalId to
createClient and it makes the link for you,
so there is no separate createConnectionClientLink call. Filed takes the
connection from your access token. That id, with the tax year and return type,
is also the client’s identity on that mutation: calling it again returns the
client you already created, with the new uploads added, even when calls arrive
at the same time. The link step above is for clients that already exist in
Filed. To create clients from the firm’s UltraTax or CCH Axcess client list,
see Create clients from tax software.
Documents attached through
initiateTaxReview or initiateTaxAdvisor are still
recorded as ordinary uploads — neither takes a source connection.Refreshing
Access tokens last three minutes. This is deliberate: the long-lived credential is the refresh token you hold, and what reaches the API is not. Exchange the refresh token whenever you need a fresh access token rather than caching one.cURL
scope, workspace_id, and
workspace_name. Filed returns the same refresh token rather than rotating
it, so there is nothing to store after a refresh.
The refresh token does not expire while you use it. It lapses only after 90
days without a refresh; when that happens, send the customer through the flow
again.
When a customer disconnects
Customers manage the connection in Filed under Plugins, where your integration appears by name alongside their others. Disconnecting revokes the grant. Because access tokens are short lived, a disconnect takes effect within three minutes at the outside. Your next refresh fails withinvalid_grant. The same
happens if the customer who approved the grant leaves the workspace, or if 90
days pass without a refresh.
Treat invalid_grant on refresh as “this connection is over”: stop retrying,
clear the stored token, and prompt the customer to reconnect if they want to
continue.
Handling failures
Some failures happen before Filed can trust yourredirect_uri: an unknown
client_id, or a URI that is not registered. Filed renders an error page in the
customer’s browser rather than redirecting, because bouncing a browser to an
unverified URI is how an open redirect is built. Check your registration if a
customer reports seeing this page.
Once the redirect URI is verified, everything comes back to you as query
parameters, per
RFC 6749:
access_denied covers three distinct situations, and the description tells you
which:
The last two are ordinary outcomes, not rare edge cases, because Filed accounts
are provisioned under contract. Filed hands the browser back to you rather than
stopping on a Filed page, so your product is the one that explains what to do
next.
The token endpoint returns JSON errors:
Current limits
Worth knowing before you build:- Scopes are not enforced field by field yet, as described above.
- There is no token revocation endpoint. The discovery document omits it rather than advertising one that does not work. Customers revoke by disconnecting.
- Refresh tokens are not rotated. Refreshing returns the same token, and a token in use does not expire, so a leaked copy stays usable until the customer disconnects.
- Authorization requests expire after 10 minutes, so a customer who leaves the consent screen open and comes back has to start again.