.do

Authentication

API keys, OAuth, and service tokens

Secure access to the .do platform APIs.

API Keys

Simple authentication for server-side applications.

Getting Started

# Get API key from dashboard
export API_KEY="your-api-key"

# Make authenticated request
curl -H "Authorization: Bearer $API_KEY" \
  https://apis.do/acme.com/businesses

SDK Usage

import { $ } from 'sdk.do'

const client = $(process.env.API_KEY)
const businesses = await client.Business.list()

Best Practices

  • Store keys in environment variables
  • Rotate keys every 90 days
  • Use different keys per environment
  • Scope keys to minimum permissions
  • Monitor usage in dashboard

OAuth 2.0

User authentication with Authorization Code + PKCE flow.

Setup

  1. Register app at platform.do/settings/oauth
  2. Get client_id and client_secret
  3. Configure redirect URIs

Authorization Flow

// 1. Redirect to authorization
const authUrl = new URL('https://platform.do/oauth/authorize')
authUrl.searchParams.set('client_id', CLIENT_ID)
authUrl.searchParams.set('redirect_uri', REDIRECT_URI)
authUrl.searchParams.set('response_type', 'code')
authUrl.searchParams.set('scope', 'read:user write:businesses')
authUrl.searchParams.set('state', randomState)
authUrl.searchParams.set('code_challenge', codeChallenge)
authUrl.searchParams.set('code_challenge_method', 'S256')

// 2. Handle callback
const tokens = await exchangeCodeForToken({
  code,
  clientId: CLIENT_ID,
  clientSecret: CLIENT_SECRET,
  redirectUri: REDIRECT_URI,
  codeVerifier
})

// 3. Use access token
const client = $(tokens.accessToken)
const user = await client.User.get('me')

Token Refresh

Access tokens expire after 1 hour:

const newTokens = await refreshAccessToken({
  refreshToken: tokens.refreshToken,
  clientId: CLIENT_ID,
  clientSecret: CLIENT_SECRET
})

Available Scopes

ScopeDescription
read:userRead user profile
write:userUpdate user profile
read:businessesList businesses
write:businessesCreate/update businesses
read:agentsRead agents
write:agentsCreate/update agents
adminFull access

Service Tokens

Long-lived credentials for workers and background jobs.

Creating Tokens

do auth:create-service-token \
  --name "my-worker" \
  --scopes "read:businesses,write:agents"

Using in Workers

// wrangler.toml
[vars]
DO_SERVICE_TOKEN = "do_service_xyz..."

// worker.ts
export default {
  async fetch(request: Request, env: Env) {
    const client = $(env.DO_SERVICE_TOKEN)
    const businesses = await client.Business.list()
    return Response.json({ businesses })
  }
}

Worker-to-Worker

Use service bindings for internal communication:

// wrangler.toml
[[services]]
binding = "API"
service = "api-worker"

// worker.ts
export default {
  async fetch(request: Request, env: Env) {
    const response = await env.API.fetch('/businesses')
    return response
  }
}

Security

  • Use secrets in production
  • Scope to minimum permissions
  • Rotate every 90 days
  • Monitor via audit logs
  • Revoke immediately if compromised

Rate Limits

All authentication methods are subject to rate limits:

PlanRequests/min
Free60
Pro600
Business6,000
EnterpriseCustom

Error Handling

try {
  const result = await client.Business.get(id)
} catch (error) {
  if (error.code === 'INVALID_API_KEY') {
    // Handle invalid credentials
  } else if (error.code === 'RATE_LIMIT_EXCEEDED') {
    // Handle rate limit
  } else if (error.code === 'INSUFFICIENT_PERMISSIONS') {
    // Handle permission error
  }
}