Developer guide
How another system reads from and prepares work in the Alpha accounting ledger: getting access, signing in, retries, limits, errors and every endpoint.
alpha_test_ work only on test servers; alpha_live_ keys work only in production.Keys and applications prepare work; a person approves it. Nobody can approve work they prepared.
API key
For external and older systems. Send the key in the Authorization header as Bearer alpha_live_…, or in an X-Api-Key header. Never put it in a web address. A key that is wrong, expired or revoked always gets the same 401 answer, so the reason never leaks.
Microsoft Entra application Client credentialsThe system signs in to Microsoft Entra ID with its own identity and gets a short-lived access token. No secret for our API is stored here, and IT can withdraw access in Entra.
For systems in Alpha's Microsoft tenant. Request a token with the client credentials flow for the scope api://<Alpha API client id>/.default and send it as a bearer token. The application must be registered on API clients and granted an app role by IT.
Read the live register (curl)
Any key with register:read can do this.
curl -H "Authorization: Bearer $ALPHA_API_KEY" \
"https://alpha-multi-currency-accounting-4ul.vercel.app/v1/register?pageSize=5"Capture and validate a premium (curl)
Every write needs a new Idempotency-Key. Send the same key again only to retry the same request.
curl -X POST "https://alpha-multi-currency-accounting-4ul.vercel.app/v1/policies/VALTERRA-2026/premiums" \
-H "Authorization: Bearer $ALPHA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"action":"VALIDATE","inceptionDate":"2026-06-01","currency":"USD","lines":[{"productCode":"AAR","coverCode":"PROPERTY_DAMAGE","grossAmountFcy":"1000.00","taxFcy":"0.00"}],"commission":{"rate":"0.20","basis":"GROSS_PREMIUM"},"binderFee":{"rate":"0.15","basis":"GROSS_PREMIUM"},"rateRequest":{"sourcePolicy":"APPROVED_PROVIDER_REGISTRY"}}'Read the live register (PowerShell)
Keep the key in an environment variable or a secret store, not in the script.
$headers = @{ Authorization = "Bearer $env:ALPHA_API_KEY" }
Invoke-RestMethod -Uri "https://alpha-multi-currency-accounting-4ul.vercel.app/v1/register?pageSize=5" -Headers $headersCapture and validate a premium (PowerShell)
ConvertTo-Json needs -Depth for the nested lines.
$headers = @{
Authorization = "Bearer $env:ALPHA_API_KEY"
"Idempotency-Key" = [guid]::NewGuid().ToString()
}
$body = @{ action = "VALIDATE"; inceptionDate = "2026-06-01"; currency = "USD"; lines = @(@{ productCode = "AAR"; coverCode = "PROPERTY_DAMAGE"; grossAmountFcy = "1000.00"; taxFcy = "0.00" }); commission = @{ rate = "0.20"; basis = "GROSS_PREMIUM" }; binderFee = @{ rate = "0.15"; basis = "GROSS_PREMIUM" }; rateRequest = @{ sourcePolicy = "APPROVED_PROVIDER_REGISTRY" } } | ConvertTo-Json -Depth 5
Invoke-RestMethod -Method Post -Uri "https://alpha-multi-currency-accounting-4ul.vercel.app/v1/policies/VALTERRA-2026/premiums" -Headers $headers -ContentType "application/json" -Body $bodySign in with Microsoft Entra ID (PowerShell, client credentials)
For applications in Alpha's Microsoft tenant. The application must be registered on API clients and granted an app role.
$token = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token" -Body @{
client_id = $env:CLIENT_ID
client_secret = $env:CLIENT_SECRET
scope = "api://<Alpha API client id>/.default"
grant_type = "client_credentials"
}
Invoke-RestMethod -Uri "https://alpha-multi-currency-accounting-4ul.vercel.app/v1/me" -Headers @{ Authorization = "Bearer $($token.access_token)" }Idempotency-Key header, unique per intended change (a GUID works). Retrying with the same key and body returns the first answer with idempotencyReplayed: true and creates nothing new.{ ok: true, data, correlationId }; failure is { ok: false, error: { code, message, violations[] }, correlationId }. Money and rates are decimal strings, never numbers.page (from 1) and pageSize (1 to 100, default 25) and return pagination with the total. Lists marked "Exports" below also return every matching row as a file with format=csv or format=xlsx.X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; over the limit the answer is 429 with Retry-After in seconds.| Status | Codes | Meaning |
|---|---|---|
| 400 | MALFORMED_REQUEST | The body is not valid JSON, or a write has no Idempotency-Key. |
| 401 | AUTHENTICATION_REQUIREDAPI_KEY_INVALID | No usable credentials. A refused key always gets the same answer, whether it is unknown, wrong, expired or revoked. |
| 403 | INSUFFICIENT_PERMISSIONCSRF_ORIGIN_REJECTED | The caller may not do this, maker-checker refused it, or the endpoint is for signed-in people only. |
| 404 | RESOURCE_NOT_FOUND | No such record. |
| 409 | IDEMPOTENCY_PAYLOAD_CONFLICTIDEMPOTENCY_REQUEST_IN_PROGRESSTRANSACTION_CONFLICT | The Idempotency-Key was used with another body, the same request is still running, or the records changed meanwhile. Retry the last two. |
| 422 | VALIDATION_FAILEDa business rule code | A field or an accounting rule failed. violations[] names each field, with array positions such as lines.1.coverCode. |
| 429 | RATE_LIMITED | Too many requests this minute. Wait for the seconds in Retry-After. |
| 500 | INTERNAL_ERRORAPI_KEY_CONFIGURATION_ERROR | Something went wrong on our side, or the server is not set up for API keys yet. Quote the correlation ID. |
Who is calling and what they may do.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/me | Who is calling, their roles and permissions | Signed in | Yes |
| GET | /v1/me/tours | Guided tours the signed-in person has finished | Signed in | People only |
| PUT | /v1/me/tours/{key} | Record that a guided tour was finished or dismissed | Signed in | People only |
| DELETE | /v1/me/tours/{key} | Forget a guided tour's state so it shows again | Signed in | People only |
Policies, counterparties and accounts.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/policies | List policies | register:read | Yes |
| POST | /v1/policies | Create a policy with an existing or new counterparty and accountNeeds an Idempotency-Key. | policy:manage | Yes |
| GET | /v1/policies/{policyId} | One policy with its premiums and claims | register:read | Yes |
Capture, validate and post premiums.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| POST | /v1/policies/{policyId}/premiums | Capture or validate a premium for a policyNeeds an Idempotency-Key. | premium:prepare | Yes |
| GET | /v1/premiums | List premiumsExports: format=xlsx. | premium:read | Yes |
| GET | /v1/premiums/{premiumId} | One premium with rate evidence and audit timeline | premium:read | Yes |
| PATCH | /v1/premiums/{premiumId} | Validate, withdraw, or approve and post a premiumNeeds an Idempotency-Key. | premium:prepare or premium:approve | Yes |
Bank receipts and their allocation to premium lines.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/premium-lines/open | Open premium lines a receipt can be allocated to | receipt:prepare or premium:read | Yes |
| GET | /v1/receipts | List bank receiptsExports: format=xlsx. | receipt:read | Yes |
| POST | /v1/receipts | Capture a bank receipt as a draftNeeds an Idempotency-Key. | receipt:prepare | Yes |
| GET | /v1/receipts/{receiptId} | One receipt with its allocation and audit timeline | receipt:read | Yes |
| POST | /v1/receipts/{receiptId}/allocations | Save, validate or post a receipt allocationNeeds an Idempotency-Key. | receipt:prepare or receipt:approve | Yes |
Broker commission, fees and remittances.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| POST | /v1/remuneration | Record commission and fee components for a premiumNeeds an Idempotency-Key. | remuneration:prepare | Yes |
| POST | /v1/remittances | Submit a ZAR remittance and record the insurer's acceptanceNeeds an Idempotency-Key. | remittance:approve | People only |
Claims, reserve movements and payments.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/claims | List claimsExports: format=xlsx. | claim:read | Yes |
| POST | /v1/claims | Register a claim with zero balancesNeeds an Idempotency-Key. | claim:register | Yes |
| GET | /v1/claims/{claimId} | One claim with movements, payments, rate evidence and audit timeline | claim:read | Yes |
| POST | /v1/claims/{claimId}/movements | Save, validate or post a reserve movementNeeds an Idempotency-Key. | claim:prepare or claim:approve | Yes |
| POST | /v1/claims/{claimId}/payments | Save, validate or post a claim paymentNeeds an Idempotency-Key. | claim:prepare or claim:approve | Yes |
Premium and claims statements.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/statements | List statement drafts and issued versions | statement:read | Yes |
| GET | /v1/statements/{statementId} | One statement with its versions | statement:read | Yes |
| POST | /v1/accounts/{accountId}/statements | Preview a statement, or issue itNeeds an Idempotency-Key. | statement:prepare or statement:approve | Yes |
| POST | /v1/statements/{statementId}/submit | Submit a previewed statement for approvalNeeds an Idempotency-Key. | statement:prepare | Yes |
| POST | /v1/statements/{statementId}/withdraw | Withdraw a submitted statement back to draftNeeds an Idempotency-Key. | statement:prepare | Yes |
| GET | /v1/statements/{statementId}/versions/{version}/document | Download an issued statement PDF | statement:read | Yes |
The maker-checker inbox. People only: keys and applications never approve.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/approvals | Items waiting for approval that the caller may see | approvals:read | Yes |
| POST | /v1/approvals/{type}/{id}/approve | Approve and post or issue an itemNeeds an Idempotency-Key. | premium:approve or receipt:approve or claim:approve or statement:approve or period:close | People only |
| POST | /v1/approvals/{type}/{id}/reject | Reject an item with a reasonNeeds an Idempotency-Key. | premium:approve or receipt:approve or claim:approve or statement:approve or period:close | People only |
Month-end close runs.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/close-runs | List close runs | period:prepare or period:close or audit:read | Yes |
| GET | /v1/close-runs/{closeRunId} | One close run with its items, snapshot hash and reconciliation | period:prepare or period:close or audit:read | Yes |
| POST | /v1/accounting-periods/{period}/close | Validate a month-end close, or validate and post itNeeds an Idempotency-Key. | period:prepare or period:close | Yes |
| GET | /v1/close-runs/{closeRunId}/report.xlsx | Download the close-run report workbook | period:prepare or period:close or audit:read | Yes |
The live register and the audit history.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/register | Filter or export the live registerExports: format=csv, format=xlsx. | register:read | Yes |
| GET | /v1/audit-events | Filter or export the audit historyExports: format=csv, format=xlsx. | audit:read | Yes |
| GET | /v1/entities/{entityType}/{entityId}/audit | Audit timeline of one record | Signed in | Yes |
Lookups, bank profiles and rate providers.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/lookups | Legal entities, accounts, policies, products, currencies and periods | register:read | Yes |
| GET | /v1/bank-profiles | Approved bank profiles | register:read | Yes |
| GET | /v1/rate-providers | Approved exchange-rate providers | register:read | Yes |
| POST | /v1/rate-snapshots | Fetch today's exchange rates now (once a day) | settings:manage | People only |
Excel and CSV import batches.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/imports | List import batches the caller may see | import:read or import:create | Yes |
| POST | /v1/imports | Start an import batchNeeds an Idempotency-Key. | import:create | Yes |
| GET | /v1/imports/{id} | One import batch with its row results and created records | import:read or import:create | Yes |
| POST | /v1/imports/{id}/rows | Send up to 500 rows of a batch, as text, for checkingNeeds an Idempotency-Key. | import:create | Yes |
| POST | /v1/imports/{id}/validate | Check every row against the ledger again | import:create | Yes |
| POST | /v1/imports/{id}/commit | Create draft records from valid rows (resumable) | import:create | Yes |
| POST | /v1/imports/{id}/submit | Send the created drafts for approval | import:create | Yes |
| POST | /v1/imports/{id}/cancel | Cancel a batch that has not been committed | import:create | Yes |
| GET | /v1/imports/{id}/errors.xlsx | Download the rows with problems as a workbook | import:read or import:create | Yes |
| GET | /v1/imports/templates/{file} | Download an import template, for example premium.xlsx or premium.csv | import:read or import:create | Yes |
| POST | /v1/imports/{id}/graph-source | Read a batch's file from SharePoint or OneDrive | import:create | People only |
Management reports and search.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/reports | The management reports the caller may run | register:read | Yes |
| GET | /v1/reports/{report} | Run or export a management reportExports: format=csv, format=xlsx. | register:read | Yes |
| GET | /v1/search | Search records the caller may read | Signed in | People only |
SharePoint and OneDrive. Signed-in people only.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/integrations/graph/status | Whether SharePoint and OneDrive can be used, and why not | Signed in | People only |
| POST | /v1/integrations/graph/test | Test the Microsoft Graph connection | integration:manage | People only |
| GET | /v1/integrations/graph/drives | The signed-in person's OneDrive, or the libraries of a SharePoint site | statement:read or register:read or audit:read or import:create or integration:manage | People only |
| GET | /v1/integrations/graph/sites | Search SharePoint sites | statement:read or register:read or audit:read or import:create or integration:manage | People only |
| GET | /v1/integrations/graph/drives/{driveId}/children | Folders and files in a drive folder | statement:read or register:read or audit:read or import:create or integration:manage | People only |
| POST | /v1/integrations/graph/publish | Save a statement or export to SharePoint or OneDriveNeeds an Idempotency-Key. | statement:read or register:read or audit:read or import:create or integration:manage | People only |
| GET | /v1/integrations/graph/publications | Recent saves to SharePoint and OneDrive, with failures | integration:manage | People only |
| POST | /v1/integrations/graph/publications/{id}/retry | Try a failed save againNeeds an Idempotency-Key. | integration:manage | People only |
| GET | /v1/integrations/graph/auto-publish | Settings for saving issued statements to SharePoint automatically | integration:manage | People only |
| PUT | /v1/integrations/graph/auto-publish | Change the automatic publishing settingsNeeds an Idempotency-Key. | integration:manage | People only |
API clients, keys and the access log. Signed-in administrators only.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/admin/api-clients | API clients with their keys and usage | apikey:manage | People only |
| POST | /v1/admin/api-clients | Register an API client or a Microsoft Entra applicationNeeds an Idempotency-Key. | apikey:manage | People only |
| GET | /v1/admin/api-clients/{clientId} | One API client with its keys and recent access | apikey:manage | People only |
| PATCH | /v1/admin/api-clients/{clientId} | Change a client's permissions or rate limit, or switch it off or onNeeds an Idempotency-Key. | apikey:manage | People only |
| POST | /v1/admin/api-clients/{clientId}/keys | Create an API key; the full key is in this response onlyNeeds an Idempotency-Key. | apikey:manage | People only |
| POST | /v1/admin/api-clients/{clientId}/keys/{keyId}/revoke | Revoke an API key immediatelyNeeds an Idempotency-Key. | apikey:manage | People only |
| GET | /v1/admin/api-access-log | Recent requests made with API keys and client applications | apikey:manage | People only |
This document.
| Method | Path | What it does | Permission | Other systems |
|---|---|---|---|---|
| GET | /v1/openapi.json | This OpenAPI 3.1 document | None (public) | Yes |
| GET | /v1/openapi | This OpenAPI document inside the response envelope (kept for older callers) | None (public) | Yes |