API reference

The portal speaks to dispute-api over HTTP. Every route lives under the /v1 prefix. All authenticated routes require a Heimdall-issued bearer token in the Authorization header. CORS is enabled for the portal and marketing-site origins.

Auth

POST/v1/auth/signup

Create an account. Returns access and refresh tokens. Triggers a fire-and-forget email-verification dispatch via Envoi.

POST/v1/auth/signin

Sign in with identifier (username or primary email) and password. Returns tokens already switched into the caller's tenant.

POST/v1/auth/refresh

Exchange a refresh token for a fresh access token.

POST/v1/auth/bootstrap

Idempotent — provisions a tenant for an authenticated user who doesn't have one yet. Returns post-switch tokens.

POST/v1/auth/verify-email/resend

Re-dispatches the 6-digit verification code via Envoi.

POST/v1/auth/verify-email/confirm

Submit the 6-digit code. Public consume — flips the contact to verified.

GET/v1/auth/me

Identity, permissions, tenant, workspace, and emailVerified flag.

Transactions

GET/v1/transactions

List with pagination, filters, and search.

GET/v1/transactions/export.csv

Stream the full transaction table as CSV.

GET/v1/transactions/:id

Single transaction with payment-event timeline.

Disputes

GET/v1/disputes

List with status / category / search / date-range filters.

GET/v1/disputes/:id

Single dispute with linked transaction and evidence list.

GET/v1/disputes/:id/events

Audit-style event history for the dispute.

POST/v1/disputes/:id/accept

Move the dispute to accepted.

POST/v1/disputes/:id/challenge

Submit a challenge after evidence is attached. Moves to under_review.

POST/v1/disputes/:id/rfi-response

Submit a text response to an RFI. Moves to rfi_responded.

POST/v1/disputes/:id/arbitrate

Escalate a lost dispute to arbitration. Adds the scheme-specific arbitration fee to the record.

POST/v1/disputes/:id/notes

Append a free-form note to the dispute's event history.

POST/v1/disputes/:id/decline-list

Block future transactions from the same card / fingerprint.

POST/v1/disputes/:id/support-case

Open a support case linked to the dispute.

POST/v1/disputes/bulk

Apply a decision (accept / challenge / etc.) to a batch of disputes in one request.

POST/v1/disputes/apply-playbook/:playbookId

Run a stored playbook over the open-disputes queue.

Evidence

Uploads use a two-step presigned-URL flow — files never traverse the API.

POST/v1/disputes/:id/evidence/upload-url

Body { filename, contentType }. Returns a short-lived PUT URL for the file plus the storageKey to send back when finalising.

POST/v1/disputes/:id/evidence

Body { storageKey, filename, contentType, kind, note? }. Finalises the evidence record after the client has PUT the file to storage. kind is one of receipt, shipping_proof, communication, refund_policy, service_documentation, other.

GET/v1/disputes/:id/evidence/:evidenceId/download-url

Short-lived presigned GET URL for the evidence file.

Reports

GET/v1/reports

List queued / running / completed reports.

POST/v1/reports

Queue a transactions or disputes CSV report.

GET/v1/reports/:id

Status + metadata for a single report.

GET/v1/reports/:id/download-url

Short-lived presigned URL for the generated CSV.

Playbooks

GET/v1/playbooks

List the tenant's playbooks.

POST/v1/playbooks

Create a playbook.

GET/v1/playbooks/:id

Single playbook with its rules.

PATCH/v1/playbooks/:id

Update name, rules, or default flag.

DELETE/v1/playbooks/:id

Delete the playbook.

POST/v1/playbooks/:id/dry-run

Run the playbook against the current open-disputes queue without applying changes.

Webhooks

GET/v1/webhooks

List configured webhook endpoints.

POST/v1/webhooks

Register a new endpoint. The HMAC secret is returned exactly once.

PATCH/v1/webhooks/:id

Edit the URL, event filter, or active flag.

DELETE/v1/webhooks/:id

Remove the webhook.

POST/v1/webhooks/:id/test

Fire a synthetic event to the endpoint and return the upstream response.

Team

GET/v1/team/synthetic-accounts

List synthetic accounts in the tenant.

POST/v1/team/synthetic-accounts

Provision a synthetic account. Returns the generated email + password once.

PATCH/v1/team/synthetic-accounts/:displayId

Update label, role, or notes.

DELETE/v1/team/synthetic-accounts/:displayId

Archive the synthetic account.

POST/v1/team/synthetic-accounts/:displayId/rotate-password

Issue a new password and return it once.

Metrics, payments, public stats

GET/v1/metrics/overview

Dashboard KPIs: chargeback ratio, win rate, totals.

GET/v1/payments/:id

Single payment lookup by display id.

GET/v1/public/stats/synthetic-payments

Unauthenticated counter feeding the marketing-page total. Rate-limited and cached server-side.

GET/v1/health

Liveness + database probe.

Dev

POST/v1/dev/generate

Generate a synthetic batch. See the Dev panel page for the field list.

POST/v1/dev/advance-lifecycle

Run the hourly background job on demand. Returns counts of moved rows.

POST/v1/dev/reset

Wipe the tenant's synthetic data.

A machine-readable schema (OpenAPI / Swagger) is on the roadmap but not yet shipped — endpoints are documented here in the meantime.