Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

OAuth Apps

OAuth apps let you build server-to-server integrations with Driftwood. They use the client credentials grant type — your app exchanges a client ID and secret for an access token, then uses that token to call the API.

┌─────────────┐ ┌──────────────────┐
│ Your App │ │ Driftwood API │
│ │ 1. POST oauth-token │ │
│ │──────────────────────→ │ │
│ │ client_id + secret │ │
│ │ │ │
│ │ ←──────────────────── │ │
│ │ 2. access_token │ │
│ │ │ │
│ │ 3. API calls with │ │
│ │──────────────────────→ │ │
│ │ Bearer token │ │
└─────────────┘ └──────────────────┘

You can create OAuth apps through the Driftwood UI (Settings → OAuth Apps) or via the API.

Terminal window
curl -X POST https://api.driftwoodapp.com/api/oauth-apps-create \
-H "Authorization: Bearer YOUR_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "My CRM Sync"}'

Response:

{
"ok": true,
"result": {
"app": {
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"account_id": "a1b2c3d4-...",
"created_by": "u1v2w3x4-...",
"name": "My CRM Sync",
"client_id": "dw_ci_k8j2m4n6p8q0",
"client_secret_prefix": "dw_cs_",
"created_at": "2025-06-01T12:00:00Z",
"updated_at": "2025-06-01T12:00:00Z"
},
"client_secret": "dw_cs_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}
}

Exchange your credentials for a token using the oauth-token endpoint:

Terminal window
curl -X POST https://api.driftwoodapp.com/api/oauth-token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "dw_ci_k8j2m4n6p8q0",
"client_secret": "dw_cs_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}'

Response:

{
"ok": true,
"result": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600
}
}

Parameters:

FieldTypeRequiredDescription
grant_typestringYesMust be "client_credentials"
client_idstringYesYour app’s client ID
client_secretstringYesYour app’s client secret

Include the token in the Authorization header of all API requests:

Terminal window
curl -X POST https://api.driftwoodapp.com/api/contacts-list \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{"limit": 25}'

OAuth access tokens expire after 1 hour. Your integration should:

  1. Cache the token and its expiration time
  2. Before each API call, check if the token is near expiry (e.g., within 5 minutes)
  3. If expired or near-expiry, request a new token
import time
import requests
class DriftwoodClient:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.token = None
self.token_expires_at = 0
def get_token(self):
if self.token and time.time() < self.token_expires_at - 300:
return self.token
resp = requests.post(
"https://api.driftwoodapp.com/api/oauth-token",
json={
"grant_type": "client_credentials",
"client_id": self.client_id,
"client_secret": self.client_secret,
},
)
data = resp.json()["result"]
self.token = data["access_token"]
self.token_expires_at = time.time() + data["expires_in"]
return self.token
def call(self, operation, body=None):
resp = requests.post(
f"https://api.driftwoodapp.com/api/{operation}",
headers={"Authorization": f"Bearer {self.get_token()}"},
json=body or {},
)
return resp.json()

OAuth app tokens inherit the permissions of the user who created the app:

  • They can access all data within the user’s account
  • They are subject to the same subscription and account-lock checks
  • They cannot perform admin operations

OAuth apps have higher rate limits than user tokens:

Auth TypeRateBurst
User token10 req/s20
OAuth token50 req/s100

See Rate Limits for details.

Terminal window
curl -X POST https://api.driftwoodapp.com/api/oauth-apps-list \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"include_revoked": false}'

Revoking an app immediately invalidates all its tokens. This cannot be undone.

Terminal window
curl -X POST https://api.driftwoodapp.com/api/oauth-apps-revoke \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"}'
FieldTypeDescription
iduuidUnique identifier
account_iduuidAccount the app belongs to
created_byuuidUser who created the app
namestringDisplay name
client_idstringPublic client identifier (prefix: dw_ci_)
client_secret_prefixstringFirst characters of the secret for identification
revoked_atdatetime | nullWhen the app was revoked, if applicable
last_used_atdatetime | nullLast time the app authenticated
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp
CodeDescription
oauth.invalid_requestMalformed request body
oauth.unsupported_grant_typeOnly client_credentials is supported
oauth.missing_credentialsMissing client_id or client_secret
oauth.invalid_clientInvalid credentials or revoked app
oauth.internalServer error