API Documentation
Everything you need to integrate with the WoodenDollars platform.
API Overview
The WoodenDollars API is a RESTful service that powers the platform. All endpoints return JSON and use standard HTTP methods and status codes. Explore the interactive Swagger documentation for a complete list of endpoints, request schemas, and response examples.
Base URL
All API requests should be made to the following base URL:
Authentication
The API supports two authentication methods: cookie-based session authentication for browser clients and API key authentication for programmatic access.
Session Authentication
Send a POST request to /auth/login with your credentials. The server will set an HTTP-only session cookie. Include credentials in all subsequent requests.
{
"email": "user@example.com",
"password": "your-password",
"tenant_short_name": "your-company"
} Set credentials: 'include' in your fetch/XHR requests to ensure the session cookie is sent.
API Key Authentication
API keys can be created from the Tenant Administration panel. Include the key in the Authorization header as a Bearer token.
Request Headers
Include the following headers with every request:
HTTP Response Codes
Error Format
When an error occurs, the response body contains a JSON object with a code and message:
{
"code": "VALIDATION_ERROR",
"message": "email is required"
}Rate Limiting
API requests are subject to rate limiting to ensure platform stability. If you exceed the limit, you will receive a 429 Too Many Requests response. Contact support if you need higher limits.
Data API
EnterpriseThe Data API allows data engineers to extract tenant data from the WoodenDollars platform for use in external pipelines, data warehouses, and reporting tools. It is available exclusively on the Enterprise plan. Access is via API key with the data_engineer scope, issued by your tenant administrator.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /v1/data/extract | Discover available tables |
| GET | /v1/data/extract/{table} | Incremental window extraction |
| GET | /v1/data/extract/{table}/current | Point-in-time snapshot extraction |
| POST | /v1/data/extract/{table}/reset | Reset the extraction cursor |
| GET | /v1/data/executions | List extraction history (session auth) |
Authentication
All data extraction endpoints require an API key with the data_engineer scope. API keys are created by your tenant administrator via Admin → User Management. Pass the key as a Bearer token:
The GET /v1/data/extract (discovery) endpoint also accepts session authentication for tenant admins and platform admins.
Discover Available Tables
Returns the list of tables you can extract data from. Only tables with a corresponding base table in the platform are listed — denied tables and internal infrastructure tables are excluded.
Response
{
"tables": [
{ "table_name": "account", "description": "" },
{ "table_name": "transaction", "description": "" }
]
}Window Extraction
Extracts rows modified since the last completed or reset extraction for this user and table. The extraction window is modified_at >= start_at AND modified_at < end_at. By default the cursor advances automatically — start_at picks up from the previous run and end_at is set to now − 5 s to avoid edge-of-window data loss.
Query Parameters
| Parameter | Default | Description |
|---|---|---|
| row_count | 1000 | Rows per page. Maximum 10 000. |
| page_number | 1 | 1-based page index. |
| data_extraction_execution_id | — | Required for page 2+. Returned on page 1. Ensures all pages share the same time window. |
| start_at | auto-cursor | Override window start. RFC3339 or Unix epoch seconds. Disables safety lag. |
| end_at | now − 5s | Override window end. RFC3339 or Unix epoch seconds. Disables safety lag. |
Current Extraction
Returns a point-in-time snapshot of the table: start_at and end_at are both set to now at execution time. Limited to 2 extractions per user per table per calendar day.
Accepts the same row_count, page_number, and data_extraction_execution_id parameters as the window endpoint. Returns 429 once the daily limit is reached.
Reset Extraction Cursor
Inserts a reset sentinel row that becomes the new cursor position for subsequent window extractions.
Response — 201 Created
{
"data_extraction_execution_id": "0194f9aa-...",
"table_name": "account",
"end_at": "2024-01-01T00:00:00Z"
}DJSON Output Format
Extraction responses use a columnar DJSON format. Use the columns array as the authoritative field index. Timestamps are UTC ISO 8601 strings. NULL values become JSON null.
{
"data_extraction_execution_id": "0194f9aa-3c12-7abc-8def-000000000001",
"columns": ["account_log_id", "account_id", "tenant_id", "balance", "modified_at", "modified_by"],
"rows": [
["0194f9aa-...", "0194f9ab-...", "0194f9ac-...", 5000, "2024-01-15T10:30:00.000000Z", "0194f9ad-..."]
]
}Pagination
- Request page 1 — note the
data_extraction_execution_idfrom the response. - If
len(rows) == row_count, request the next page with the same execution ID and incremented page number. - When
len(rows) < row_count, this is the final page.
row_count, the last data page will be full. Request one further page (returns zero rows) to trigger the completed status transition.Execution Status Lifecycle
| Status | When set |
|---|---|
| pending | On first request (page 1). |
| started | After page 1 response is sent. |
| completed | When a response contains fewer rows than row_count. |
| reset | Inserted by the reset endpoint; acts as the new cursor. |
Support
If you have questions or need help with the API, please contact our support team.