API Docs
Dashboard

Admin API

Platform-wide administration under /api/v1/admin/* — manage every business, user, plan, setting, coupon and platform invoice across the whole platform from one super-admin token.

Who can use it

Admin endpoints require a user access token belonging to a super-admin — an account whose account_type is S. Regular admins (A) and business API keys are rejected with 403; a missing or invalid token gets 401. Obtain a token the usual way, with the login flow (POST /api/v1/auth/login).

Unlike the rest of the API, admin endpoints are platform-wide, not scoped to a single business — the X-Business-Id header is ignored here, and you never pass a business id in a header. Sensitive columns (payment secrets, integration tokens, password hashes, the internal md5) are always stripped from responses.

Authenticate

# Log in as a super-admin (account_type: "S") to get an access token
curl -X POST https://app.destination.dev/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "password": "•••••••••" }'

# Then call any admin route with that token
curl "https://app.destination.dev/api/v1/admin/businesses" \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN"

403 for the wrong principal

{
  "error": {
    "type": "forbidden",
    "message": "Super-admin access required."
  },
  "meta": { "request_id": "req_1a2b3c4d5e6f7a8b" }
}

Response shape

Every response uses the shared envelope: success is { "data": … , "meta": { "request_id", "pagination"? } }; errors are { "error": { "type", "message", "details"? }, "meta": { "request_id" } }. List endpoints accept ?page and ?per_page (default 20, max 100) and return a meta.pagination block.

Businesses

  • GET /admin/businesses — list with ?search= (name / email / slug) and pagination.
  • GET /admin/businesses/{id} — full sanitised row.
  • GET /admin/businesses/{id}/usage — plan, subscription and activity stats.
  • POST /admin/businesses/{id}/credits — adjust email/booking credits.
  • POST /admin/businesses/{id}/suspend — suspend or reactivate.
  • PATCH /admin/businesses/{id} — edit whitelisted core fields.

List & search

curl "https://app.destination.dev/api/v1/admin/businesses?search=transfers&per_page=25" \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN"

Response

{
  "data": [
    {
      "business_id": 7,
      "business_name": "Executive Transfers",
      "business_email": "[email protected]",
      "vendor_slug": "executive-transfers",
      "status": "A",
      "subscription_plan_id": 3,
      "subscription_status": "active",
      "email_credits": 500,
      "currency": "EUR"
    }
  ],
  "meta": {
    "request_id": "req_9f2c1a",
    "pagination": { "page": 1, "per_page": 25, "count": 1, "total": 1, "has_more": false }
  }
}

Credits, suspend & edit

Top up (or deduct, with a negative value) a business's credits; suspend sets its status to D and activate restores A; a PATCH edits a whitelisted set of fields — pass at least one. Each returns the updated resource.

Add credits

curl -X POST https://app.destination.dev/api/v1/admin/businesses/7/credits \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "credits": 500, "reason": "Goodwill top-up" }'

Suspend

curl -X POST https://app.destination.dev/api/v1/admin/businesses/7/suspend \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "action": "suspend" }'

Edit fields

curl -X PATCH https://app.destination.dev/api/v1/admin/businesses/7 \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "business_name": "Executive Transfers Ltd", "subscription_status": "active" }'

Users

  • GET /admin/users — list with ?search= and ?account_type=S|A.
  • POST /admin/users — create an admin (default A) or super-admin. Email must be unique — a clash returns 409 email_exists.
  • GET /admin/users/{id} — read one user.
  • POST /admin/users/{id}/password-reset — set a new password (min 8 chars).
  • POST /admin/users/{id}/business-assignment — assign or unassign a business membership.

Create a user

curl -X POST https://app.destination.dev/api/v1/admin/users \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "New Operator",
    "email": "[email protected]",
    "password": "a-strong-passphrase",
    "account_type": "A"
  }'

Assign to a business

curl -X POST https://app.destination.dev/api/v1/admin/users/512/business-assignment \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "business_id": 7, "action": "assign" }'

Response

{
  "data": {
    "user_id": 512,
    "action": "assign",
    "business_id": 7,
    "business_ids": [7, 9]
  },
  "meta": { "request_id": "req_9f2c1a" }
}

Plans, coupons & platform invoices

Read-only views of the platform's subscription plans, discount coupons and subscription invoices.

  • GET /admin/plans (add ?include_inactive=true) and GET /admin/plans/{id}.
  • GET /admin/saas-coupons and GET /admin/saas-coupons/{id}.
  • GET /admin/saas-invoices (filter ?status= and ?business_id=) and GET /admin/saas-invoices/{id} (with line items & payments).

List paid platform invoices for a business

curl "https://app.destination.dev/api/v1/admin/saas-invoices?status=paid&business_id=7" \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN"

Platform settings

GET /admin/settings returns every SaaS setting grouped by category, each with its typed value, type and description. PATCH /admin/settings/{key} updates one setting by key, preserving its category and type, and returns the fresh value.

Read all settings

curl https://app.destination.dev/api/v1/admin/settings \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN"

Update one setting

curl -X PATCH https://app.destination.dev/api/v1/admin/settings/platform_name \
  -H "Authorization: Bearer SUPER_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "value": "Destination Tools" }'
Guard your super-admin token. It reaches every business and user on the platform. Keep it server-side, rotate it if exposed, and never ship it in a client app.

See the full request and response shapes for every operation — under the Admin tag — in the API reference. Read Errors for the shared error envelope.