Authentication

Choose a service account for your own organization, or an OAuth app for access to individual entities or an entire organization.

Authenticate Digits Connect API calls with a bearer access token. Choose how to obtain that token based on whose data you need and how broadly your integration should connect.

Choose your authentication mode

ModeAccessBest forAuthorization
Service accountYour own firm or organization and its clients or entitiesInternal tools and automationClient ID + secret (client_credentials); no user authorization flow
App (entity)An individual entity and its app connectionIntegrations that connect one business at a timeUser approval via OAuth (authorization_code)
App (organization)An entire organization and its clients or entitiesPractice management and firm-wide integrationsUser approval via OAuth (authorization_code)

Set up authentication

Select a mode for its setup steps and example requests. Replace the example credentials, tokens, and IDs with your own values.

✅

API Access in 2 Steps

  1. Token Request via https://connect.digits.com/v1/oauth/token using client_credentials
  2. API calls with the service account's access token, selecting an entity when needed
🔑

Access to your own organization

Service accounts belong to your firm or organization. They need no redirect URI, installation, or user consent screen. Developer accounts and sandboxes cannot create service accounts.

1. Create your service account

In your firm's or organization's Developer area, choose Create → Service Account. Enter a name and description, select the permissions (scopes) you need, and save. Copy the client ID and client secret from Credentials.

You need permission to create organization connections. Service accounts have production credentials only. For the ledger example below, enable ledger:read.

2. Request an access token

Send your credentials from your server to the token endpoint:

curl --request POST 'https://connect.digits.com/v1/oauth/token' \
  --header 'Content-Type: application/json' \
  --data '{
    "grant_type": "client_credentials",
    "client_id": "your_client_id",
    "client_secret": "your_client_secret"
  }'

Example response:

{
  "access_token": "your_access_token",
  "expires_in": 3599,
  "token_type": "Bearer",
  "scope": "ledger:read"
}

The token uses the service account's configured scopes. There is no scope parameter in this request and no refresh token. Repeat this request when the access token expires.

3. Call the API

Use the token to read your organization:

curl 'https://connect.digits.com/v1/organization' \
  --header 'Authorization: Bearer your_access_token'

To read a particular entity's chart of accounts, supply its Digits entity ID:

curl --get 'https://connect.digits.com/v1/ledger/categories' \
  --data-urlencode 'entity.id=your_digits_entity_id' \
  --header 'Authorization: Bearer your_access_token'

The entity must belong to, or be accessible by, your organization. See Selecting an entity below for more details.

Working with tokens

Access tokens last up to 1 hour. Use the response's expires_in value to schedule renewal. Every API call sends the token in the Authorization: Bearer <access_token> header.

🔒

Keep credentials on your server. Store client secrets and tokens securely, keep them out of browser code and logs, and use HTTPS for API calls and production callbacks.

Renewing access tokens

Service accounts: request another token with grant_type=client_credentials. No refresh token is issued.

Both app types: send the refresh token to the same token endpoint:

curl --request POST 'https://connect.digits.com/v1/oauth/token' \
  --header 'Content-Type: application/json' \
  --data '{
    "grant_type": "refresh_token",
    "client_id": "your_client_id",
    "client_secret": "your_client_secret",
    "refresh_token": "your_refresh_token"
  }'

The response includes a new access token and the same refresh token. Refresh tokens do not expire automatically, but disconnecting or uninstalling the app revokes them. If the refresh token is no longer valid, start a new authorization flow.

Selecting an entity

Service accounts and organization apps receive organization-level tokens. For endpoints that act on an entity or connection, use the endpoint's entity selector to identify the business you want to work with.

  • GET requests: pass entity.id as a query parameter, as shown in the tabs above.
  • JSON requests: use "entity": {"id": "your_digits_entity_id"} when the endpoint defines an entity field.

Find entity IDs through List Entities for an organization's own entities, or List Clients, then Get Client for a firm's clients. Get Client returns an entities array; use each entity's id. These discovery requests require an organization-level token with no additional scope.

Digits checks the selected entity against the organization represented by your token. An entity app's token is already bound to its authorized entity; adding a selector cannot expand its access.

Choosing scopes

Scopes control which operations a token can perform. The authentication mode controls whose data it can access. Configure only the scopes you need and check each endpoint's requirements.

ScopeAllows
ledger:readRead ledger data
source:syncSync source data into Digits
documents:writeUpload and manage documents

Service account tokens use the account's configured scopes. Apps request configured scopes in the authorization URL and receive the scopes granted for that installation. Check the token response's scope value.

Troubleshooting authentication
IssueWhat to check
Invalid client credentialsUse the client ID and secret from the same account or app environment.
Redirect URI mismatchUse the exact registered URI in both authorization and token exchange.
Invalid authorization codeCodes are single-use and short-lived. Start authorization again if a code expired or was already exchanged.
Wrong grant typeService accounts use client_credentials; both app types use authorization_code, then refresh_token.
Expired access tokenRenew the token using the method for your authentication mode.
Missing scope or wrong access levelCheck the endpoint's scopes and whether it requires organization, entity, or connection access.
Missing or inaccessible entityWith an organization-level token, supply an entity selector for entity-specific requests and verify that the organization can access it.

Next steps

Follow Working across an organization to discover entities, read two businesses with one token, and initialize source writes for each. Vault document uploads require an entity-app token; that upload endpoint does not support organization-token entity selectors.


Did this page help you?