ResourcesAPI ReferenceDeveloper API Overview
API Reference

Developer API Overview

What the server-to-server v1 API is, base URL, quick start examples, and the async write model.

Developer API Overview

This document is for developers of workspaces subscribed to the DEVELOPER product. It describes the outward-facing, server-to-server API called with a workspace API token — a different API from the internal SPA endpoints that power the Dotva Vue front-end.

Source of truth: resources/openapi/v1.yaml (OpenAPI 3.1). Interactive docs: GET /api/v1/docs (Swagger UI); raw spec at GET /api/v1/openapi.yaml.


What this API is

  • Purpose: programmatically manage virtual cards and read orders / wallet / transactions.
  • Base URL: /api/v1
  • Authentication: every request carries Authorization: Bearer <token>, where the token looks like dotva_sk_... and is created in the workspace's "Developer Settings" page.
  • Writes are asynchronous: any operation that moves money or changes card state returns 202 Accepted plus an Order, which you then poll until terminal.
  • Rate limiting + idempotency: every token and every IP has a per-minute ceiling; all write endpoints support X-Idempotency-Key for safe retries.

Prerequisites

  1. The workspace must subscribe to the DEVELOPER product (otherwise it cannot create API tokens).
  2. At least one token must be created in "Developer Settings" and granted the required abilities.
  3. If the token has an IP allowlist, the calling IP must be within it.

Quick start

# 1) Validate the token; see the bound workspace and granted abilities.
curl -s https://dotva.io/api/v1/ping \
  -H "Authorization: Bearer dotva_sk_xxx"

# Response
# {
#   "data": {
#     "workspace_slug": "acme",
#     "workspace_name": "Acme Inc.",
#     "abilities": ["cards.read", "cards.write", "wallet.read"]
#   }
# }
# 2) Issue a card (asynchronous; returns 202 + Order).
curl -s -X POST https://dotva.io/api/v1/cards \
  -H "Authorization: Bearer dotva_sk_xxx" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: order-2026-0001" \
  -d '{
        "card_product_id": 1,
        "initial_topup_amount": "100.00",
        "cardholder_first_name": "Jane",
        "cardholder_last_name": "Doe"
      }'

# 3) Poll the Order until status becomes terminal (completed / failed).
curl -s https://dotva.io/api/v1/orders/<order_uuid> \
  -H "Authorization: Bearer dotva_sk_xxx"

System

GET /ping — health / token probe

  • Ability: none (any valid token)
  • Purpose: validate the token and return the bound workspace and granted abilities.

Success 200

{
  "data": {
    "workspace_slug": "acme",
    "workspace_name": "Acme Inc.",
    "abilities": ["cards.read", "wallet.read"]
  }
}

Errors: 401 api.unauthenticated


Async write model

Write endpoints return 202 Accepted plus an Order:

{
  "data": {
    "uuid": "8f1c...",
    "type": "issue_card",
    "status": "pending",
    "related_card_id": null,
    "held_amount": "106.00",
    "currency": "USD",
    "created_at": "2026-06-08T01:00:00+00:00"
  }
}

Take the uuid and poll GET /orders/{uuid} until status reaches a terminal value (completed / failed).

See Orders & Wallet for the full Orders endpoint reference, including Order status and type enums.