Authentication

SpeyBooks uses API keys to authenticate requests. All API requests must be made over HTTPS.

API keys identify your organisation, are scoped to specific permissions, and grant access only to the resources and actions you allow.

API keys

Include your API key in the Authorization header using the Bearer scheme:

curl https://api.speybooks.com/v1/invoices \
  -H "Authorization: Bearer sk_live_your_api_key"

Key types

Type Prefix Use case
Live sk_live_ Production data
Test sk_test_ Development and testing

Test keys operate on a separate dataset. No real financial data is affected when using test keys.


Scoped permissions

API keys support 17 granular scopes in resource:action format. A key with invoices:read can list and retrieve invoices but cannot create, update, or delete them. When a key attempts an operation outside its scopes, the API returns 403 Forbidden with the required scope in the error message.

Available scopes

Scope Description
accounts:read List and retrieve chart of accounts
accounts:write Create, update, delete accounts
contacts:read List and retrieve contacts
contacts:write Create, update, deactivate contacts
invoices:read List, retrieve, and download invoices
invoices:write Create, update, delete, send invoices
quotes:read List and retrieve quotes
quotes:write Create, update, delete, convert quotes
transactions:read List and retrieve transactions
transactions:write Create, categorise, reconcile transactions
reports:read Generate P&L, balance sheet, VAT returns
bank-imports:read List and retrieve bank imports
bank-imports:write Upload, confirm, delete bank imports
directors:read List directors, DLA balances, snapshots
directors:write Add, update, resign directors, manage DLA
dividends:read List dividends, board minutes, summaries
dividends:write Declare, pay, void dividends

Scope recommendations

Use case Recommended scopes
Reporting dashboard invoices:read, reports:read, contacts:read
Invoicing automation invoices:write, contacts:read
Bank import script bank-imports:write, transactions:read
Full access All scopes (or omit scopes to grant everything)

Generating API keys

Via the web portal

  1. Log in to app.speybooks.com
  2. Navigate to Settings > API Keys
  3. Click Generate API Key
  4. Enter a descriptive name and select scopes
  5. Copy the key immediately - it will not be shown again

Via the API

curl -X POST https://api.speybooks.com/v1/api-keys \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Reporting dashboard",
    "scopes": ["invoices:read", "reports:read", "contacts:read"]
  }'

The full key value is returned once in the response. Store it securely. It cannot be retrieved again - only the prefix (first 8 characters) is visible after creation.

Rotating API keys

To rotate a key without downtime:

curl -X POST https://api.speybooks.com/v1/api-keys/key_1/rotate \
  -H "Authorization: Bearer sk_live_..."

This generates a new key with the same name and scopes, and revokes the old one. Update your application with the new key from the response.

Revoking API keys

To revoke a compromised or unused key:

curl -X DELETE https://api.speybooks.com/v1/api-keys/key_1 \
  -H "Authorization: Bearer sk_live_..."

The key is invalidated immediately. All subsequent requests using that key return 401 Unauthorized.


Idempotency keys

For mutation requests (POST, PATCH, PUT, DELETE), include an Idempotency-Key header to make the request safely retryable:

curl -X POST https://api.speybooks.com/v1/invoices \
  -H "Authorization: Bearer sk_live_..." \
  -H "Idempotency-Key: inv-feb-acme" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

If the same idempotency key is sent again within 24 hours, SpeyBooks returns the original response instead of creating a duplicate. If the original request failed with a 5xx error, the key is released and can be retried.

Idempotency keys are optional but strongly recommended for any automated workflow.

Request requirements

All API requests must include:

  • An Authorization header with a valid Bearer token
  • Content-Type: application/json for POST, PUT, and PATCH requests

Response format

All responses use a consistent JSON envelope:

{
  "success": true,
  "data": { ... },
  "meta": { "total": 47 }
}

Error responses include a machine-readable code, a human-readable message, and an optional field for validation errors:

{
  "success": false,
  "error": {
    "code": "validation_error",
    "message": "The 'email' field is required",
    "field": "email"
  }
}

Rate limits

Requests are rate limited per endpoint to ensure fair usage.

When the limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating when requests may resume.

Security best practices

Never expose API keys in client-side code API keys are intended for server-side use only. Never include them in browser JavaScript, mobile apps, or public repositories.
  • Use environment variables - store keys in environment variables, not source code
  • Scope keys to minimum permissions - a reporting key shouldn't be able to delete contacts
  • Rotate keys periodically - generate new keys and revoke old ones to limit exposure
  • Use test keys for development - keep production data isolated from testing
export SPEYBOOKS_API_KEY="sk_live_..."
curl https://api.speybooks.com/v1/invoices \
  -H "Authorization: Bearer $SPEYBOOKS_API_KEY"

Testing authentication

Verify that your API key is valid by fetching your organisation:

curl https://api.speybooks.com/v1/organisation \
  -H "Authorization: Bearer sk_live_your_api_key"

A valid key returns your organisation details. An invalid or missing key returns 401 Unauthorized.

Related endpoints