Open Mercato
Covo API
Version 0.6.3
OpenAPI JSONMarkdown Docs

OpenAPI Explorer

Auto-generated OpenAPI definition for all enabled modules.

Default server: https://admin.getcovo.com/api

Authentication & Accounts

Showing 20 of 35 endpoints
GET/auth/admin/nav
Auth required

Resolve backend chrome bootstrap payload

Returns the backend chrome payload available to the authenticated administrator after applying scope, RBAC, role defaults, and personal sidebar preferences.

Responses

200Backend chrome payload
Content-Type: application/json
{
  "groups": [
    {
      "name": "string",
      "items": [
        {
          "href": "string",
          "title": "string"
        }
      ]
    }
  ],
  "settingsSections": [
    {
      "id": "string",
      "label": "string",
      "items": [
        {
          "id": "string",
          "label": "string",
          "href": "string"
        }
      ]
    }
  ],
  "settingsPathPrefixes": [
    "string"
  ],
  "profileSections": [
    {
      "id": "string",
      "label": "string",
      "items": [
        {
          "id": "string",
          "label": "string",
          "href": "string"
        }
      ]
    }
  ],
  "profilePathPrefixes": [
    "string"
  ],
  "grantedFeatures": [
    "string"
  ],
  "roles": [
    "string"
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/auth/admin/nav" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/auth/feature-check
Auth required

Check feature grants for the current user

Evaluates which of the requested features are available to the signed-in user within the active tenant / organization context.

Request body (application/json)

{
  "features": [
    "string"
  ]
}

Responses

200Evaluation result
Content-Type: application/json
{
  "ok": true,
  "granted": [
    "string"
  ],
  "userId": "string"
}
400Invalid request — features array missing, too large, or contains invalid entries
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/auth/feature-check" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"features\": [
    \"string\"
  ]
}"
GET/auth/features
Auth requiredauth.acl.manage

List declared feature flags

Returns all static features contributed by the enabled modules along with their module source. Requires features: auth.acl.manage

Responses

200Aggregated feature catalog
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "module": "string"
    }
  ],
  "modules": [
    {
      "id": "string",
      "title": "string"
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/auth/features" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/locale

Set locale and redirect

Stores the selected locale in a cookie and redirects to a safe local path.

Parameters

NameInRequiredSchemaDescription
localequeryYesany
redirectqueryNoany

Responses

200Success response
Content-Type: application/json
"string"
302Locale cookie set and request redirected
Content-Type: application/json
"string"
400Invalid locale
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/auth/locale?locale=en" \
  -H "Accept: application/json"
POST/auth/locale

Set locale

Stores the selected locale in a cookie and returns a JSON success response.

Request body (application/json)

{
  "locale": "en"
}

Responses

200Locale cookie set
Content-Type: application/json
{
  "ok": true
}
400Invalid locale or malformed request body
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/auth/locale" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"locale\": \"en\"
}"
POST/auth/login

Authenticate user credentials

Validates the submitted credentials and issues a bearer token cookie for subsequent API calls.

Request body (application/x-www-form-urlencoded)

email=user%40example.com&password=string

Responses

200Authentication succeeded
Content-Type: application/json
{
  "ok": true,
  "token": "string",
  "redirect": null
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Invalid credentials
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403User lacks required role
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many login attempts
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/auth/login" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "email=user%40example.com&password=string"
GET/auth/logout
Auth required

Log out (legacy GET)

For convenience, the GET variant performs the same logout logic as POST and issues a redirect.

Responses

200Success response
Content-Type: application/json
"string"
302Redirect to login after successful logout
Content-Type: text/html
string

Example

curl -X GET "https://admin.getcovo.com/api/auth/logout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/auth/logout
Auth required

Invalidate session and redirect

Clears authentication cookies and redirects the browser to the login page.

Responses

201Success response
Content-Type: application/json
"string"
302Redirect to login after successful logout
Content-Type: text/html
string

Example

curl -X POST "https://admin.getcovo.com/api/auth/logout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/profile
Auth required

Get current profile

Returns the email address for the signed-in user.

Responses

200Profile payload
Content-Type: application/json
{
  "email": "user@example.com",
  "roles": [
    "string"
  ]
}
404User not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/auth/profile" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/auth/profile
Auth required

Update current profile

Updates the email address or password for the signed-in user.

Request body (application/json)

{}

Responses

200Profile updated
Content-Type: application/json
{
  "ok": true,
  "email": "user@example.com"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/auth/profile" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/auth/reset

Send reset email

Requests a password reset email for the given account. The endpoint always returns `ok: true` to avoid leaking account existence.

Request body (application/x-www-form-urlencoded)

email=user%40example.com

Responses

200Reset email dispatched (or ignored for unknown accounts)
Content-Type: application/json
{
  "ok": true
}
400Invalid request origin
Content-Type: application/json
{
  "error": "string"
}
429Too many password reset requests
Content-Type: application/json
{
  "error": "string"
}
500Password reset email origin is not configured
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/auth/reset" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "email=user%40example.com"
POST/auth/reset/confirm

Complete password reset

Validates the reset token and updates the user password.

Request body (application/x-www-form-urlencoded)

token=string&password=string

Responses

200Password reset succeeded
Content-Type: application/json
{
  "ok": true,
  "redirect": "string"
}
400Invalid token or payload
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many reset confirmation attempts
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/auth/reset/confirm" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=string&password=string"
GET/auth/roles
Auth requiredauth.roles.list

List roles

Returns available roles within the current tenant. Super administrators receive visibility across tenants. Requires features: auth.roles.list

Parameters

NameInRequiredSchemaDescription
idqueryNoany
pagequeryNoany
pageSizequeryNoany
searchqueryNoany
tenantIdqueryNoany

Responses

200Role collection
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "usersCount": 1,
      "tenantId": null,
      "tenantName": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/auth/roles?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/auth/roles
Auth requiredauth.roles.manage

Create role

Creates a new role for the current tenant or globally when `tenantId` is omitted. Requires features: auth.roles.manage

Request body (application/json)

{
  "name": "string"
}

Responses

201Role created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/auth/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
PUT/auth/roles
Auth requiredauth.roles.manage

Update role

Updates mutable fields on an existing role. Requires features: auth.roles.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Role updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/auth/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/auth/roles
Auth requiredauth.roles.manage

Delete role

Deletes a role by identifier. Fails when users remain assigned. Requires features: auth.roles.manage

Parameters

NameInRequiredSchemaDescription
idqueryYesanyRole identifier

Responses

200Role deleted
Content-Type: application/json
{
  "ok": true
}
400Role cannot be deleted
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/auth/roles?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/roles/acl
Auth requiredauth.acl.manage

Fetch role ACL

Returns the feature and organization assignments associated with a role within the current tenant. Requires features: auth.acl.manage

Parameters

NameInRequiredSchemaDescription
roleIdqueryYesany
tenantIdqueryNoany

Responses

200Role ACL entry
Content-Type: application/json
{
  "isSuperAdmin": true,
  "features": [
    "string"
  ],
  "organizations": null
}
400Invalid role id
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/auth/roles/acl?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/auth/roles/acl
Auth requiredauth.acl.manage

Update role ACL

Replaces the feature list, super admin flag, and optional organization assignments for a role. Requires features: auth.acl.manage

Request body (application/json)

{
  "roleId": "00000000-0000-4000-8000-000000000000",
  "organizations": null
}

Responses

200Role ACL updated
Content-Type: application/json
{
  "ok": true,
  "sanitized": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/auth/roles/acl" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"roleId\": \"00000000-0000-4000-8000-000000000000\",
  \"organizations\": null
}"
GET/auth/session/refresh

Refresh auth cookie from session token (browser)

Exchanges an existing `session_token` cookie for a fresh JWT auth cookie and redirects the browser.

Parameters

NameInRequiredSchemaDescription
redirectqueryNoanyAbsolute or relative URL to redirect after refresh

Responses

200Success response
Content-Type: application/json
"string"
302Redirect to target location when session is valid
Content-Type: text/html
string

Example

curl -X GET "https://admin.getcovo.com/api/auth/session/refresh" \
  -H "Accept: application/json"
POST/auth/session/refresh

Refresh access token (API/mobile)

Exchanges a refresh token for a new JWT access token. Pass the refresh token obtained from login in the request body.

Request body (application/json)

{
  "refreshToken": "string"
}

Responses

200New access token issued
Content-Type: application/json
{
  "ok": true,
  "accessToken": "string",
  "expiresIn": 1
}
400Missing refresh token
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Invalid or expired token
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many refresh attempts
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/auth/session/refresh" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"refreshToken\": \"string\"
}"

Directory (Tenants & Organizations)

Showing 2 of 2 endpoints
GET/directory/organizations/lookup

Public organization lookup by slug

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/directory/organizations/lookup" \
  -H "Accept: application/json"
GET/directory/tenants/lookup

Public tenant lookup

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/directory/tenants/lookup" \
  -H "Accept: application/json"

Audit & Action Logs

Showing 5 of 5 endpoints
GET/audit_logs/audit-logs/access
Auth requiredaudit_logs.view_self

Retrieve access logs

Fetches paginated access audit logs scoped to the authenticated user. Tenant administrators can optionally expand the search to other actors or organizations. Requires features: audit_logs.view_self

Parameters

NameInRequiredSchemaDescription
organizationIdqueryNoanyLimit results to a specific organization
actorUserIdqueryNoanyFilter by actor user id (tenant administrators only)
resourceKindqueryNoanyRestrict to a resource kind such as `order` or `product`
accessTypequeryNoanyAccess type filter, e.g. `read` or `export`
pagequeryNoanyPage number (default 1)
pageSizequeryNoanyPage size (default 50)
limitqueryNoanyExplicit maximum number of records when paginating manually
beforequeryNoanyReturn logs created before this ISO-8601 timestamp
afterqueryNoanyReturn logs created after this ISO-8601 timestamp

Responses

200Access logs returned successfully
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "resourceKind": "string",
      "resourceId": "string",
      "accessType": "string",
      "actorUserId": null,
      "actorUserName": null,
      "tenantId": null,
      "tenantName": null,
      "organizationId": null,
      "organizationName": null,
      "fields": [
        "string"
      ],
      "context": null,
      "createdAt": "string"
    }
  ],
  "canViewTenant": true,
  "page": 1,
  "pageSize": 1,
  "total": 1,
  "totalPages": 1
}
400Invalid filters supplied
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/audit_logs/audit-logs/access" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/audit_logs/audit-logs/actions
Auth requiredaudit_logs.view_self

Fetch action logs

Returns recent action audit log entries. Tenant administrators can widen the scope to other actors or organizations, and callers can optionally restrict results to undoable actions. Requires features: audit_logs.view_self

Parameters

NameInRequiredSchemaDescription
organizationIdqueryNoanyLimit results to a specific organization
actorUserIdqueryNoanyFilter logs created by specific actor IDs (tenant administrators only). Accepts a single UUID or a comma-separated UUID list.
resourceKindqueryNoanyFilter by resource kind (e.g., "order", "product")
resourceIdqueryNoanyFilter by resource ID (UUID of the specific record)
actionTypequeryNoanyFilter by action type (`create`, `edit`, `delete`, `assign`). Accepts a single value or a comma-separated list.
fieldNamequeryNoanyFilter to entries where the given field changed. Accepts a single field name or a comma-separated list.
includeRelatedqueryNoanyWhen `true`, also returns changes to child entities linked via parentResourceKind/parentResourceId
includeTotalqueryNoanyWhen `true`, the response includes the filtered total count.
undoableOnlyqueryNoanyWhen `true`, only undoable actions are returned
limitqueryNoanyMaximum number of records to return (default 50, max 1000)
offsetqueryNoanyZero-based record offset for pagination (legacy — prefer page/pageSize)
pagequeryNoanyPage number (default 1)
pageSizequeryNoanyPage size (default 50, max 200)
sortFieldqueryNoanySort field: `createdAt`, `user`, `action`, `field`, or `source`.
sortDirqueryNoanySort direction: `asc` or `desc`.
beforequeryNoanyReturn actions created before this ISO-8601 timestamp
afterqueryNoanyReturn actions created after this ISO-8601 timestamp

Responses

200Action logs retrieved successfully
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "commandId": "string",
      "actionLabel": null,
      "executionState": "done",
      "actorUserId": null,
      "actorUserName": null,
      "tenantId": null,
      "tenantName": null,
      "organizationId": null,
      "organizationName": null,
      "resourceKind": null,
      "resourceId": null,
      "parentResourceKind": null,
      "parentResourceId": null,
      "undoToken": null,
      "createdAt": "string",
      "updatedAt": "string",
      "snapshotBefore": null,
      "snapshotAfter": null,
      "changes": null,
      "context": null
    }
  ],
  "canViewTenant": true,
  "page": 1,
  "pageSize": 1,
  "total": 1,
  "totalPages": 1
}
400Invalid filter values
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/audit_logs/audit-logs/actions?includeRelated=false&includeTotal=false&undoableOnly=false" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/audit_logs/audit-logs/actions/export
Auth requiredaudit_logs.view_self

Export action logs as CSV

Returns a CSV attachment containing filtered action audit log entries. Tenant administrators can widen the scope to other actors or organizations. Requires features: audit_logs.view_self

Parameters

NameInRequiredSchemaDescription
organizationIdqueryNoanyLimit results to a specific organization
actorUserIdqueryNoanyFilter logs created by specific actor IDs (tenant administrators only). Accepts a single UUID or a comma-separated UUID list.
resourceKindqueryNoanyFilter by resource kind (e.g., "order", "product")
resourceIdqueryNoanyFilter by resource ID (UUID of the specific record)
actionTypequeryNoanyFilter by action type (`create`, `edit`, `delete`, `assign`). Accepts a single value or a comma-separated list.
fieldNamequeryNoanyFilter to entries where the given field changed. Accepts a single field name or a comma-separated list.
includeRelatedqueryNoanyWhen `true`, also returns changes to child entities linked via parentResourceKind/parentResourceId
undoableOnlyqueryNoanyWhen `true`, only undoable actions are returned
limitqueryNoanyMaximum number of records to export (default 1000, capped at 1000)
sortFieldqueryNoanySort field: `createdAt`, `user`, `action`, `field`, or `source`.
sortDirqueryNoanySort direction: `asc` or `desc`.
beforequeryNoanyReturn actions created before this ISO-8601 timestamp
afterqueryNoanyReturn actions created after this ISO-8601 timestamp

Responses

200CSV export generated successfully
Content-Type: application/json
{
  "file": "csv"
}
400Invalid filter values
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/audit_logs/audit-logs/actions/export?includeRelated=false&undoableOnly=false" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/audit_logs/audit-logs/actions/redo
Auth requiredaudit_logs.redo_self

Redo by action log id

Redoes the latest undone command owned by the caller. Requires the action to still be eligible for redo within tenant and organization scope. Requires features: audit_logs.redo_self

Request body (application/json)

{
  "logId": "string"
}

Responses

200Redo executed successfully
Content-Type: application/json
{
  "ok": true,
  "logId": null,
  "undoToken": null
}
400Log not eligible for redo
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/audit_logs/audit-logs/actions/redo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"logId\": \"string\"
}"
POST/audit_logs/audit-logs/actions/undo
Auth requiredaudit_logs.undo_self

Undo action by token

Replays the undo handler registered for a command. The provided undo token must match the latest undoable log entry accessible to the caller. Requires features: audit_logs.undo_self

Request body (application/json)

{
  "undoToken": "string"
}

Responses

200Undo applied successfully
Content-Type: application/json
{
  "ok": true,
  "logId": "string"
}
400Invalid or unavailable undo token
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/audit_logs/audit-logs/actions/undo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"undoToken\": \"string\"
}"

Progress

Showing 6 of 6 endpoints
GET/progress/active
Auth required

GET /progress/active

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/progress/active" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/progress/jobs
Auth required

List progressjobs

Returns a paginated collection of progressjobs scoped to the authenticated tenant.

Parameters

NameInRequiredSchemaDescription
statusqueryNoany
jobTypequeryNoany
parentJobIdqueryNoany
includeCompletedqueryNoany
completedSincequeryNoany
pagequeryNoany
pageSizequeryNoany
searchqueryNoany
sortFieldqueryNoany
sortDirqueryNoany
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated progressjobs
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "jobType": "string",
      "name": "string",
      "description": null,
      "status": "string",
      "progressPercent": 1,
      "processedCount": 1,
      "totalCount": null,
      "etaSeconds": null,
      "cancellable": true,
      "startedAt": null,
      "finishedAt": null,
      "errorMessage": null,
      "createdAt": null,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/progress/jobs?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/progress/jobs
Auth requiredprogress.create

Create progressjob

Creates a new progress job for tracking a long-running operation. Requires features: progress.create

Request body (application/json)

{
  "jobType": "string",
  "name": "string",
  "cancellable": false
}

Responses

201ProgressJob created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://admin.getcovo.com/api/progress/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"jobType\": \"string\",
  \"name\": \"string\",
  \"cancellable\": false
}"
GET/progress/jobs/{id}
Auth required

GET /progress/jobs/{id}

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/progress/jobs/{id}
Auth requiredprogress.update

PUT /progress/jobs/{id}

Requires features: progress.update

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://admin.getcovo.com/api/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/progress/jobs/{id}
Auth requiredprogress.cancel

DELETE /progress/jobs/{id}

Requires features: progress.cancel

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

204Success

No response body.

Example

curl -X DELETE "https://admin.getcovo.com/api/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Attachments

Showing 14 of 14 endpoints
GET/attachments
Auth requiredattachments.view

List attachments for a record

Returns uploaded attachments for the given entity record, ordered by newest first. Requires features: attachments.view

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesanyEntity identifier that owns the attachments
recordIdqueryYesanyRecord identifier within the entity
pagequeryNoany
pageSizequeryNoany

Responses

200Attachments found for the record
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "url": "string",
      "fileName": "string",
      "fileSize": 1,
      "createdAt": "string",
      "mimeType": null,
      "content": null
    }
  ]
}
400Missing entity or record identifiers
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/attachments?entityId=string&recordId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/attachments
Auth requiredattachments.manage

Upload attachment

Uploads a new attachment using multipart form-data and stores metadata for later retrieval. Requires features: attachments.manage

Request body (multipart/form-data)

entityId=string
recordId=string
file=string

Responses

200Attachment stored successfully
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "string",
    "url": "string",
    "fileName": "string",
    "fileSize": 1,
    "content": null
  }
}
400Payload validation error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/attachments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: multipart/form-data" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\",
  \"file\": \"string\"
}"
DELETE/attachments
Auth requiredattachments.manage

Delete attachment

Removes an uploaded attachment and deletes the stored asset. Requires features: attachments.manage

Parameters

NameInRequiredSchemaDescription
idqueryYesany

Responses

200Attachment deleted
Content-Type: application/json
{
  "ok": true
}
400Missing attachment identifier
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/attachments?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/attachments/file/{id}

Download or serve attachment file

Returns the raw file content for an attachment. Path parameter: {id} - Attachment UUID. Query parameter: ?download=1 - Force file download with Content-Disposition header. Access control is enforced based on partition settings.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200File content with appropriate MIME type
Content-Type: application/json
"string"
400Missing attachment ID
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized - authentication required for private partitions
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Attachment or file not found
Content-Type: application/json
{
  "error": "string"
}
500Partition misconfigured
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/attachments/file/:id" \
  -H "Accept: application/json"
GET/attachments/image/{id}/{slug}

Serve image with optional resizing

Returns an image attachment with optional on-the-fly resizing and cropping. Resized images are cached for performance. Only works with image MIME types. Path parameter: {id} - Attachment UUID. Query parameters: ?width=N (1-4000 pixels), ?height=N (1-4000 pixels), ?cropType=cover|contain (resize behavior).

Parameters

NameInRequiredSchemaDescription
idpathYesany
slugpathNoany

Responses

200Binary image content (Content-Type: image/jpeg, image/png, etc.)
Content-Type: application/json
"string"
400Invalid parameters, missing ID, or non-image attachment
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized - authentication required for private partitions
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Image not found
Content-Type: application/json
{
  "error": "string"
}
500Partition misconfigured or image rendering failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/attachments/image/:id/:slug" \
  -H "Accept: application/json"
GET/attachments/library
Auth requiredattachments.view

List attachments

Returns paginated list of attachments with optional filtering by search term, partition, and tags. Includes available tags and partitions. Requires features: attachments.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoanyPage number for pagination
pageSizequeryNoanyNumber of items per page (max 100)
searchqueryNoanySearch by file name (case-insensitive)
partitionqueryNoanyFilter by partition code
tagsqueryNoanyFilter by tags (comma-separated)
sortFieldqueryNoanyField to sort by
sortDirqueryNoanySort direction

Responses

200Attachments list with pagination and metadata
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "fileName": "string",
      "fileSize": 1,
      "mimeType": "string",
      "partitionCode": "string",
      "partitionTitle": null,
      "url": null,
      "createdAt": "string",
      "tags": [
        "string"
      ],
      "assignments": [],
      "content": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1,
  "availableTags": [
    "string"
  ],
  "partitions": [
    {
      "code": "string",
      "title": "string",
      "description": null,
      "isPublic": true
    }
  ]
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/attachments/library?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/attachments/library/{id}
Auth requiredattachments.view

Get attachment details

Returns complete details of an attachment including metadata, tags, assignments, and custom fields. Requires features: attachments.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Attachment details
Content-Type: application/json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "fileName": "string",
    "fileSize": 1,
    "mimeType": "string",
    "partitionCode": "string",
    "partitionTitle": null,
    "tags": [
      "string"
    ],
    "assignments": [],
    "content": null,
    "customFields": null
  }
}
400Invalid attachment ID
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/attachments/library/{id}
Auth requiredattachments.manage

Update attachment metadata

Updates attachment tags, assignments, and custom fields. Emits CRUD side effects for indexing and events. Requires features: attachments.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{}

Responses

200Attachment updated successfully
Content-Type: application/json
{
  "ok": true
}
400Invalid payload or attachment ID
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to save attributes
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
DELETE/attachments/library/{id}
Auth requiredattachments.manage

Delete attachment

Permanently deletes an attachment file from storage and database. Emits CRUD side effects. Requires features: attachments.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Attachment deleted successfully
Content-Type: application/json
{
  "ok": true
}
400Invalid attachment ID
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/attachments/partitions
Auth requiredattachments.manage

List all attachment partitions

Returns all configured attachment partitions with storage settings, OCR configuration, and access control settings. Requires features: attachments.manage

Responses

200List of partitions
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "title": "string",
      "description": null,
      "isPublic": true,
      "requiresOcr": true,
      "ocrModel": null,
      "configJson": null,
      "createdAt": null,
      "updatedAt": null,
      "envKey": "string"
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/attachments/partitions
Auth requiredattachments.manage

Create new partition

Creates a new attachment partition with specified storage and OCR settings. Requires unique partition code. Requires features: attachments.manage

Request body (application/json)

{
  "code": "string",
  "title": "string",
  "description": null,
  "ocrModel": null,
  "storageDriver": "local",
  "configJson": null
}

Responses

201Partition created successfully
Content-Type: application/json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "code": "string",
    "title": "string",
    "description": null,
    "isPublic": true,
    "requiresOcr": true,
    "ocrModel": null,
    "configJson": null,
    "createdAt": null,
    "updatedAt": null,
    "envKey": "string"
  }
}
400Invalid payload or partition code
Content-Type: application/json
{
  "error": "string"
}
409Partition code already exists
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"title\": \"string\",
  \"description\": null,
  \"ocrModel\": null,
  \"storageDriver\": \"local\",
  \"configJson\": null
}"
PUT/attachments/partitions
Auth requiredattachments.manage

Update partition

Updates an existing partition. Partition code cannot be changed. Title, description, OCR settings, and access control can be modified. Requires features: attachments.manage

Request body (application/json)

{
  "code": "string",
  "title": "string",
  "description": null,
  "ocrModel": null,
  "storageDriver": "local",
  "configJson": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Partition updated successfully
Content-Type: application/json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "code": "string",
    "title": "string",
    "description": null,
    "isPublic": true,
    "requiresOcr": true,
    "ocrModel": null,
    "configJson": null,
    "createdAt": null,
    "updatedAt": null,
    "envKey": "string"
  }
}
400Invalid payload or code change attempt
Content-Type: application/json
{
  "error": "string"
}
404Partition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"title\": \"string\",
  \"description\": null,
  \"ocrModel\": null,
  \"storageDriver\": \"local\",
  \"configJson\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/attachments/partitions
Auth requiredattachments.manage

Delete partition

Deletes a partition. Default partitions cannot be deleted. Partitions with existing attachments cannot be deleted. Requires features: attachments.manage

Responses

200Partition deleted successfully
Content-Type: application/json
{
  "ok": true
}
400Invalid ID or default partition deletion attempt
Content-Type: application/json
{
  "error": "string"
}
404Partition not found
Content-Type: application/json
{
  "error": "string"
}
409Partition in use
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/attachments/transfer
Auth requiredattachments.manage

Transfer attachments to different record

Transfers one or more attachments from one record to another within the same entity type. Updates attachment assignments and metadata to reflect the new record. Requires features: attachments.manage

Request body (application/json)

{
  "entityId": "string",
  "attachmentIds": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "toRecordId": "string"
}

Responses

200Attachments transferred successfully
Content-Type: application/json
{
  "ok": true,
  "updated": 1
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Attachments not found
Content-Type: application/json
{
  "error": "string"
}
500Attachment model missing
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/attachments/transfer" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"attachmentIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ],
  \"toRecordId\": \"string\"
}"

S3-Compatible Storage

Showing 5 of 5 endpoints
DELETE/storage-providers/s3/delete

Delete file from S3

Responses

204Success

No response body.

Example

curl -X DELETE "https://admin.getcovo.com/api/storage-providers/s3/delete" \
  -H "Accept: application/json"
GET/storage-providers/s3/download

Download file from S3

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/storage-providers/s3/download" \
  -H "Accept: application/json"
GET/storage-providers/s3/list

List S3 objects

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/storage-providers/s3/list" \
  -H "Accept: application/json"
POST/storage-providers/s3/signed-url

Generate S3 pre-signed URL

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/storage-providers/s3/signed-url" \
  -H "Accept: application/json"
POST/storage-providers/s3/upload

Upload file to S3

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/storage-providers/s3/upload" \
  -H "Accept: application/json"

API Keys

Showing 3 of 3 endpoints
GET/api_keys/keys
Auth requiredapi_keys.view

List API keys

Returns paginated API keys visible to the current user, including per-key role assignments and organization context. Requires features: api_keys.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
searchqueryNoany

Responses

200Collection of API keys
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "name": "string",
      "description": null,
      "keyPrefix": "string",
      "organizationId": null,
      "organizationName": null,
      "createdAt": "string",
      "lastUsedAt": null,
      "expiresAt": null,
      "roles": [
        {
          "id": "string",
          "name": null
        }
      ]
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Tenant context missing
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/api_keys/keys" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/api_keys/keys
Auth requiredapi_keys.create

Create API key

Creates a new API key, returning the one-time secret value together with the generated key prefix and scope details. Requires features: api_keys.create

Request body (application/json)

{
  "name": "string",
  "description": null,
  "tenantId": null,
  "organizationId": null,
  "roles": [],
  "expiresAt": null
}

Responses

201API key created successfully
Content-Type: application/json
{
  "id": "string",
  "name": "string",
  "keyPrefix": "string",
  "tenantId": null,
  "organizationId": null,
  "roles": [
    {
      "id": "string",
      "name": null
    }
  ]
}
400Invalid payload or missing tenant context
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/api_keys/keys" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"description\": null,
  \"tenantId\": null,
  \"organizationId\": null,
  \"roles\": [],
  \"expiresAt\": null
}"
DELETE/api_keys/keys
Auth requiredapi_keys.delete

Delete API key

Removes an API key by identifier. The key must belong to the current tenant and fall within the requester organization scope. Requires features: api_keys.delete

Parameters

NameInRequiredSchemaDescription
idqueryYesanyAPI key identifier to delete

Responses

200Key deleted successfully
Content-Type: application/json
{
  "success": true
}
400Missing or invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Key not found within scope
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/api_keys/keys?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

API Documentation

Showing 1 of 1 endpoints
GET/version

Deployed Open Mercato version

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/version" \
  -H "Accept: application/json"

Feature Toggles

Showing 12 of 12 endpoints
GET/feature_toggles/check/boolean
Auth required

Check if feature is enabled

Checks if a feature toggle is enabled for the current context.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200Feature status
Content-Type: application/json
{
  "enabled": true,
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/check/boolean?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/check/json
Auth required

Get json config

Gets the json configuration for a feature toggle.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200Json config
Content-Type: application/json
{
  "valueType": "json",
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/check/json?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/check/number
Auth required

Get number config

Gets the number configuration for a feature toggle.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200Number config
Content-Type: application/json
{
  "valueType": "number",
  "value": 1,
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/check/number?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/check/string
Auth required

Get string config

Gets the string configuration for a feature toggle.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200String config
Content-Type: application/json
{
  "valueType": "string",
  "value": "string",
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/check/string?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global
Auth requiredfeature_toggles.view

List global feature toggles

Returns all global feature toggles with filtering and pagination. Requires superadmin role. Requires features: feature_toggles.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoanyPage number for pagination
pageSizequeryNoanyNumber of items per page (max 200)
searchqueryNoanyCase-insensitive search across identifier, name, description, and category
typequeryNoanyFilter by toggle type (boolean, string, number, json)
categoryqueryNoanyFilter by category (case-insensitive partial match)
namequeryNoanyFilter by name (case-insensitive partial match)
identifierqueryNoanyFilter by identifier (case-insensitive partial match)
sortFieldqueryNoanyField to sort by
sortDirqueryNoanySort direction (ascending or descending)

Responses

200Feature toggles collection
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "identifier": "string",
      "name": "string",
      "description": null,
      "category": null,
      "type": "boolean",
      "defaultValue": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/global?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/feature_toggles/global
Auth requiredfeature_toggles.manage

Create global feature toggle

Creates a new global feature toggle. Requires superadmin role. Requires features: feature_toggles.manage

Request body (application/json)

{
  "identifier": "string",
  "name": "string",
  "description": null,
  "category": null,
  "type": "boolean",
  "defaultValue": null
}

Responses

201Feature toggle created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/feature_toggles/global" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"identifier\": \"string\",
  \"name\": \"string\",
  \"description\": null,
  \"category\": null,
  \"type\": \"boolean\",
  \"defaultValue\": null
}"
PUT/feature_toggles/global
Auth requiredfeature_toggles.manage

Update global feature toggle

Updates an existing global feature toggle. Requires superadmin role. Requires features: feature_toggles.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "description": null,
  "category": null,
  "defaultValue": null
}

Responses

200Feature toggle updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/feature_toggles/global" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"description\": null,
  \"category\": null,
  \"defaultValue\": null
}"
DELETE/feature_toggles/global
Auth requiredfeature_toggles.manage

Delete global feature toggle

Soft deletes a global feature toggle by ID. Requires superadmin role. Requires features: feature_toggles.manage

Parameters

NameInRequiredSchemaDescription
idqueryYesanyFeature toggle identifier

Responses

200Feature toggle deleted
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/feature_toggles/global?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global/{id}
Auth requiredfeature_toggles.view

Fetch feature toggle by ID

Returns complete details of a feature toggle. Requires features: feature_toggles.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Feature toggle detail
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "identifier": "string",
  "name": "string",
  "description": null,
  "category": null,
  "type": "boolean",
  "defaultValue": null
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/global/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global/{id}/override
Auth requiredfeature_toggles.view

Fetch feature toggle override

Returns feature toggle override. Requires features: feature_toggles.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Feature toggle overrides
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "tenantName": "string",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "toggleType": "boolean"
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/global/:id/override" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/overrides
Auth requiredfeature_toggles.view

List overrides

Returns list of feature toggle overrides. Requires features: feature_toggles.view

Parameters

NameInRequiredSchemaDescription
categoryqueryNoany
namequeryNoany
identifierqueryNoany
sortFieldqueryNoany
sortDirqueryNoany
pagequeryNoany
pageSizequeryNoany

Responses

200List of overrides
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "toggleId": "00000000-0000-4000-8000-000000000000",
      "overrideState": "enabled",
      "identifier": "string",
      "name": "string",
      "category": null,
      "defaultState": true,
      "tenantName": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1,
  "isSuperAdmin": true
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/feature_toggles/overrides?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/feature_toggles/overrides
Auth requiredfeature_toggles.manage

Change override state

Enable, disable or inherit a feature toggle for a specific tenant. Requires features: feature_toggles.manage

Request body (application/json)

{
  "toggleId": "00000000-0000-4000-8000-000000000000",
  "isOverride": true
}

Responses

200Override updated
Content-Type: application/json
{
  "ok": true,
  "overrideToggleId": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/feature_toggles/overrides" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"toggleId\": \"00000000-0000-4000-8000-000000000000\",
  \"isOverride\": true
}"

Business Rules

Showing 17 of 17 endpoints
POST/business_rules/execute
Auth requiredbusiness_rules.execute

Execute rules for given context

Manually executes applicable business rules for the specified entity type, event, and data. Supports dry-run mode to test rules without executing actions. Requires features: business_rules.execute

Request body (application/json)

{
  "entityType": "string",
  "dryRun": false
}

Responses

200Rules executed successfully
Content-Type: application/json
{
  "allowed": true,
  "executedRules": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "conditionResult": true,
      "executionTime": 1
    }
  ],
  "totalExecutionTime": 1
}
400Invalid request payload
Content-Type: application/json
{
  "error": "string"
}
500Execution error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/business_rules/execute" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\",
  \"dryRun\": false
}"
POST/business_rules/execute/{ruleId}
Auth requiredbusiness_rules.execute

Execute a specific rule by its database UUID

Directly executes a specific business rule identified by its UUID, bypassing the normal entityType/eventType discovery mechanism. Useful for workflows and targeted rule execution. Requires features: business_rules.execute

Parameters

NameInRequiredSchemaDescription
ruleIdpathYesanyThe database UUID of the business rule to execute

Request body (application/json)

{
  "dryRun": false
}

Responses

200Rule executed successfully
Content-Type: application/json
{
  "success": true,
  "ruleId": "string",
  "ruleName": "string",
  "conditionResult": true,
  "actionsExecuted": null,
  "executionTime": 1
}
400Invalid request payload or rule ID
Content-Type: application/json
{
  "error": "string"
}
404Rule not found
Content-Type: application/json
{
  "error": "string"
}
500Execution error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/business_rules/execute/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"dryRun\": false
}"
GET/business_rules/logs
Auth requiredbusiness_rules.view_logs

List rule execution logs

Returns rule execution history for the current tenant and organization with filtering and pagination. Useful for audit trails and debugging. Requires features: business_rules.view_logs

Parameters

NameInRequiredSchemaDescription
idqueryNoany
pagequeryNoany
pageSizequeryNoany
ruleIdqueryNoany
entityIdqueryNoany
entityTypequeryNoany
executionResultqueryNoany
executedByqueryNoany
executedAtFromqueryNoany
executedAtToqueryNoany
sortFieldqueryNoany
sortDirqueryNoany

Responses

200Rule execution logs collection
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "ruleId": "string",
      "ruleName": "string",
      "ruleType": "string",
      "entityId": "00000000-0000-4000-8000-000000000000",
      "entityType": "string",
      "executionResult": "SUCCESS",
      "inputContext": null,
      "outputContext": null,
      "errorMessage": null,
      "executionTimeMs": 1,
      "executedAt": "string",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": null,
      "executedBy": null
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/business_rules/logs?page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/business_rules/logs/{id}
Auth requiredbusiness_rules.view_logs

Get execution log detail

Returns detailed information about a specific rule execution, including full context and results. Requires features: business_rules.view_logs

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Log entry details
Content-Type: application/json
{
  "id": "string",
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "ruleId": "string",
    "ruleName": "string",
    "ruleType": "string",
    "entityType": "string"
  },
  "entityId": "00000000-0000-4000-8000-000000000000",
  "entityType": "string",
  "executionResult": "SUCCESS",
  "inputContext": null,
  "outputContext": null,
  "errorMessage": null,
  "executionTimeMs": 1,
  "executedAt": "string",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": null,
  "executedBy": null
}
400Invalid log id
Content-Type: application/json
{
  "error": "string"
}
404Log entry not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/business_rules/logs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/business_rules/rules
Auth requiredbusiness_rules.view

List business rules

Returns business rules for the current tenant and organization with filtering and pagination. Requires features: business_rules.view

Parameters

NameInRequiredSchemaDescription
idqueryNoany
pagequeryNoany
pageSizequeryNoany
searchqueryNoany
ruleIdqueryNoany
ruleTypequeryNoany
entityTypequeryNoany
eventTypequeryNoany
enabledqueryNoany
ruleCategoryqueryNoany
sortFieldqueryNoany
sortDirqueryNoany

Responses

200Business rules collection
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "ruleId": "string",
      "ruleName": "string",
      "description": null,
      "ruleType": "GUARD",
      "ruleCategory": null,
      "entityType": "string",
      "eventType": null,
      "enabled": true,
      "priority": 1,
      "version": 1,
      "effectiveFrom": null,
      "effectiveTo": null,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/business_rules/rules?page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/business_rules/rules
Auth requiredbusiness_rules.manage

Create business rule

Creates a new business rule for the current tenant and organization. Requires features: business_rules.manage

Request body (application/json)

{
  "ruleId": "string",
  "ruleName": "string",
  "description": null,
  "ruleType": "GUARD",
  "ruleCategory": null,
  "entityType": "string",
  "eventType": null,
  "enabled": true,
  "priority": 100,
  "version": 1,
  "effectiveFrom": null,
  "effectiveTo": null,
  "tenantId": "string",
  "organizationId": "string",
  "createdBy": null,
  "conditionExpression": null,
  "successActions": null,
  "failureActions": null
}

Responses

201Business rule created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/business_rules/rules" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"ruleId\": \"string\",
  \"ruleName\": \"string\",
  \"description\": null,
  \"ruleType\": \"GUARD\",
  \"ruleCategory\": null,
  \"entityType\": \"string\",
  \"eventType\": null,
  \"enabled\": true,
  \"priority\": 100,
  \"version\": 1,
  \"effectiveFrom\": null,
  \"effectiveTo\": null,
  \"tenantId\": \"string\",
  \"organizationId\": \"string\",
  \"createdBy\": null,
  \"conditionExpression\": null,
  \"successActions\": null,
  \"failureActions\": null
}"
PUT/business_rules/rules
Auth requiredbusiness_rules.manage

Update business rule

Updates an existing business rule. Requires features: business_rules.manage

Request body (application/json)

{
  "description": null,
  "ruleCategory": null,
  "eventType": null,
  "enabled": true,
  "priority": 100,
  "version": 1,
  "effectiveFrom": null,
  "effectiveTo": null,
  "conditionExpression": null,
  "successActions": null,
  "failureActions": null,
  "id": "string"
}

Responses

200Business rule updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Business rule not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/business_rules/rules" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"description\": null,
  \"ruleCategory\": null,
  \"eventType\": null,
  \"enabled\": true,
  \"priority\": 100,
  \"version\": 1,
  \"effectiveFrom\": null,
  \"effectiveTo\": null,
  \"conditionExpression\": null,
  \"successActions\": null,
  \"failureActions\": null,
  \"id\": \"string\"
}"
DELETE/business_rules/rules
Auth requiredbusiness_rules.manage

Delete business rule

Soft deletes a business rule by identifier. Requires features: business_rules.manage

Parameters

NameInRequiredSchemaDescription
idqueryYesanyBusiness rule identifier

Responses

200Business rule deleted
Content-Type: application/json
{
  "ok": true
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Business rule not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/business_rules/rules?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/business_rules/rules/{id}
Auth requiredbusiness_rules.view

Fetch business rule by ID

Returns complete details of a business rule including conditions and actions. Requires features: business_rules.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Business rule detail
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "ruleId": "string",
  "ruleName": "string",
  "description": null,
  "ruleType": "GUARD",
  "ruleCategory": null,
  "entityType": "string",
  "eventType": null,
  "successActions": null,
  "failureActions": null,
  "enabled": true,
  "priority": 1,
  "version": 1,
  "effectiveFrom": null,
  "effectiveTo": null,
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "createdBy": null,
  "updatedBy": null,
  "createdAt": "string",
  "updatedAt": "string"
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Business rule not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/business_rules/rules/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/business_rules/sets
Auth requiredbusiness_rules.view

List rule sets

Returns rule sets for the current tenant and organization with filtering and pagination. Requires features: business_rules.view

Parameters

NameInRequiredSchemaDescription
idqueryNoany
pagequeryNoany
pageSizequeryNoany
searchqueryNoany
setIdqueryNoany
enabledqueryNoany
sortFieldqueryNoany
sortDirqueryNoany

Responses

200Rule sets collection
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "setId": "string",
      "setName": "string",
      "description": null,
      "enabled": true,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdBy": null,
      "updatedBy": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/business_rules/sets?page=1&pageSize=50&sortDir=asc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/business_rules/sets
Auth requiredbusiness_rules.manage_sets

Create rule set

Creates a new rule set for organizing business rules. Requires features: business_rules.manage_sets

Request body (application/json)

{
  "setId": "string",
  "setName": "string",
  "description": null,
  "enabled": true,
  "tenantId": "string",
  "organizationId": "string",
  "createdBy": null
}

Responses

201Rule set created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/business_rules/sets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"setId\": \"string\",
  \"setName\": \"string\",
  \"description\": null,
  \"enabled\": true,
  \"tenantId\": \"string\",
  \"organizationId\": \"string\",
  \"createdBy\": null
}"
PUT/business_rules/sets
Auth requiredbusiness_rules.manage_sets

Update rule set

Updates an existing rule set. Requires features: business_rules.manage_sets

Request body (application/json)

{
  "description": null,
  "enabled": true,
  "id": "string"
}

Responses

200Rule set updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Rule set not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/business_rules/sets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"description\": null,
  \"enabled\": true,
  \"id\": \"string\"
}"
DELETE/business_rules/sets
Auth requiredbusiness_rules.manage_sets

Delete rule set

Soft deletes a rule set by identifier. Requires features: business_rules.manage_sets

Parameters

NameInRequiredSchemaDescription
idqueryYesanyRule set identifier

Responses

200Rule set deleted
Content-Type: application/json
{
  "ok": true
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Rule set not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/business_rules/sets?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/business_rules/sets/{id}
Auth requiredbusiness_rules.view

Get rule set detail

Returns detailed information about a specific rule set, including all member rules. Requires features: business_rules.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Rule set details
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "setId": "string",
  "setName": "string",
  "description": null,
  "enabled": true,
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "createdBy": null,
  "updatedBy": null,
  "createdAt": "string",
  "updatedAt": "string",
  "members": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "ruleId": "00000000-0000-4000-8000-000000000000",
      "ruleName": "string",
      "ruleType": "string",
      "sequence": 1,
      "enabled": true
    }
  ]
}
400Invalid rule set id
Content-Type: application/json
{
  "error": "string"
}
404Rule set not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/business_rules/sets/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/business_rules/sets/{id}/members
Auth requiredbusiness_rules.manage_sets

Add rule to set

Adds a business rule to a rule set with specified sequence and enabled state. Requires features: business_rules.manage_sets

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "ruleId": "00000000-0000-4000-8000-000000000000",
  "sequence": 0,
  "enabled": true
}

Responses

201Member added
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Rule set or rule not found
Content-Type: application/json
{
  "error": "string"
}
409Rule already in set
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/business_rules/sets/:id/members" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"ruleId\": \"00000000-0000-4000-8000-000000000000\",
  \"sequence\": 0,
  \"enabled\": true
}"
PUT/business_rules/sets/{id}/members
Auth requiredbusiness_rules.manage_sets

Update set member

Updates sequence or enabled state of a rule set member. Requires features: business_rules.manage_sets

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "memberId": "00000000-0000-4000-8000-000000000000"
}

Responses

200Member updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Member not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/business_rules/sets/:id/members" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"memberId\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/business_rules/sets/{id}/members
Auth requiredbusiness_rules.manage_sets

Remove rule from set

Removes a business rule from a rule set (hard delete). Requires features: business_rules.manage_sets

Parameters

NameInRequiredSchemaDescription
idpathYesany
memberIdqueryYesanyMember identifier

Responses

200Member removed
Content-Type: application/json
{
  "ok": true
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Member not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/business_rules/sets/:id/members?memberId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Search

Showing 15 of 15 endpoints
GET/search/embeddings
Auth requiredsearch.embeddings.view

Get embeddings configuration

Returns current embedding provider and model configuration. Requires features: search.embeddings.view

Responses

200Embeddings settings
Content-Type: application/json
{
  "settings": {
    "openaiConfigured": true,
    "autoIndexingEnabled": true,
    "autoIndexingLocked": true,
    "lockReason": null,
    "embeddingConfig": null,
    "configuredProviders": [
      "openai"
    ],
    "indexedDimension": null,
    "reindexRequired": true,
    "documentCount": null
  }
}

Example

curl -X GET "https://admin.getcovo.com/api/search/embeddings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/search/embeddings
Auth requiredsearch.embeddings.manage

Update embeddings configuration

Updates the embedding provider and model settings. Requires features: search.embeddings.manage

Request body (application/json)

{}

Responses

200Updated settings
Content-Type: application/json
{
  "settings": {
    "openaiConfigured": true,
    "autoIndexingEnabled": true,
    "autoIndexingLocked": true,
    "lockReason": null,
    "embeddingConfig": null,
    "configuredProviders": [
      "openai"
    ],
    "indexedDimension": null,
    "reindexRequired": true,
    "documentCount": null
  }
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
409Auto-indexing disabled via environment
Content-Type: application/json
{
  "error": "string"
}
500Update failed
Content-Type: application/json
{
  "error": "string"
}
503Configuration service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/search/embeddings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/search/embeddings/reindex
Auth requiredsearch.embeddings.manage

Trigger vector reindex

Starts a vector embedding reindex operation. Requires features: search.embeddings.manage

Request body (application/json)

{}

Responses

200Reindex result
Content-Type: application/json
{
  "ok": true
}
409Reindex already in progress
Content-Type: application/json
{
  "error": "string",
  "lock": {
    "type": "fulltext",
    "action": "string",
    "startedAt": "string",
    "elapsedMinutes": 1,
    "processedCount": null,
    "totalCount": null
  }
}
500Reindex failed
Content-Type: application/json
{
  "error": "string"
}
503Search indexer unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/search/embeddings/reindex" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/search/embeddings/reindex/cancel
Auth requiredsearch.embeddings.manage

Cancel vector reindex

Cancels an in-progress vector reindex operation. Requires features: search.embeddings.manage

Responses

200Cancel result
Content-Type: application/json
{
  "ok": true,
  "jobsRemoved": 1
}

Example

curl -X POST "https://admin.getcovo.com/api/search/embeddings/reindex/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/index
Auth requiredsearch.view

List vector index entries

Returns paginated list of entries in the vector search index. Requires features: search.view

Parameters

NameInRequiredSchemaDescription
entityIdqueryNoanyFilter by entity ID (e.g., "customers:customer_person_profile", "catalog:catalog_product")
limitqueryNoanyMaximum entries to return (default: 50, max: 200)
offsetqueryNoanyOffset for pagination (default: 0)

Responses

200Index entries
Content-Type: application/json
{
  "entries": [
    {
      "id": "string",
      "entityId": "string",
      "recordId": "string",
      "tenantId": "string",
      "organizationId": null
    }
  ],
  "limit": 1,
  "offset": 1
}
500Failed to fetch index
Content-Type: application/json
{
  "error": "string"
}
503Vector strategy unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/search/index" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/search/index
Auth requiredsearch.embeddings.manage

Purge vector index

Purges entries from the vector search index. Requires confirmAll=true when purging all entities. Requires features: search.embeddings.manage

Parameters

NameInRequiredSchemaDescription
entityIdqueryNoanySpecific entity ID to purge (e.g., "customers:customer_person_profile", "catalog:catalog_product")
confirmAllqueryNoanyRequired when purging all entities

Responses

200Purge result
Content-Type: application/json
{
  "ok": true
}
400Missing confirmAll parameter
Content-Type: application/json
{
  "error": "string"
}
500Purge failed
Content-Type: application/json
{
  "error": "string"
}
503Search indexer unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/search/index" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/search/reindex
Auth requiredsearch.reindex

Trigger fulltext reindex

Starts a fulltext (Meilisearch) reindex operation. Can clear, recreate, or fully reindex. Requires features: search.reindex

Request body (application/json)

{}

Responses

200Reindex result
Content-Type: application/json
{
  "ok": true,
  "action": "clear",
  "entityId": null
}
409Reindex already in progress
Content-Type: application/json
{
  "error": "string",
  "lock": {
    "type": "fulltext",
    "action": "string",
    "startedAt": "string",
    "elapsedMinutes": 1,
    "processedCount": null,
    "totalCount": null
  }
}
500Reindex failed
Content-Type: application/json
{
  "error": "string"
}
503Search service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/search/reindex" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/search/reindex/cancel
Auth requiredsearch.reindex

Cancel fulltext reindex

Cancels an in-progress fulltext reindex operation. Requires features: search.reindex

Responses

200Cancel result
Content-Type: application/json
{
  "ok": true,
  "jobsRemoved": 1
}

Example

curl -X POST "https://admin.getcovo.com/api/search/reindex/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/search/global
Auth requiredsearch.view

Global search (Cmd+K)

Performs a global search using saved tenant strategies. Does NOT accept strategies from URL. Requires features: search.view

Parameters

NameInRequiredSchemaDescription
qqueryYesanySearch query (required)
limitqueryNoanyMaximum results to return (default: 50, max: 100)
entityTypesqueryNoanyComma-separated entity types to filter results (e.g., "customers:customer_person_profile,catalog:catalog_product,sales:sales_order")

Responses

200Search results
Content-Type: application/json
{
  "results": [
    {
      "entityId": "string",
      "recordId": "string",
      "score": 1,
      "source": "fulltext"
    }
  ],
  "strategiesUsed": [
    "fulltext"
  ],
  "strategiesEnabled": [
    "fulltext"
  ],
  "timing": 1,
  "query": "string",
  "limit": 1
}
400Missing query parameter
Content-Type: application/json
{
  "error": "string"
}
500Search failed
Content-Type: application/json
{
  "error": "string"
}
503Search service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/search/search/global?q=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/settings
Auth requiredsearch.view

Get search settings and status

Returns search module configuration, available strategies, and reindex lock status. Requires features: search.view

Responses

200Search settings
Content-Type: application/json
{
  "settings": {
    "strategies": [
      {
        "id": "string",
        "name": "string",
        "priority": 1,
        "available": true
      }
    ],
    "fulltextConfigured": true,
    "fulltextStats": null,
    "vectorConfigured": true,
    "tokensEnabled": true,
    "defaultStrategies": [
      "string"
    ],
    "reindexLock": null,
    "fulltextReindexLock": null,
    "vectorReindexLock": null
  }
}

Example

curl -X GET "https://admin.getcovo.com/api/search/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/settings/fulltext
Auth requiredsearch.view

Get fulltext search configuration

Returns Meilisearch configuration status and index statistics. Requires features: search.view

Responses

200Fulltext settings
Content-Type: application/json
{
  "driver": null,
  "configured": true,
  "envVars": {
    "MEILISEARCH_HOST": {
      "set": true,
      "hint": "string"
    },
    "MEILISEARCH_API_KEY": {
      "set": true,
      "hint": "string"
    }
  },
  "optionalEnvVars": {
    "MEILISEARCH_INDEX_PREFIX": {
      "set": true,
      "hint": "string"
    },
    "SEARCH_EXCLUDE_ENCRYPTED_FIELDS": {
      "set": true,
      "hint": "string"
    }
  }
}

Example

curl -X GET "https://admin.getcovo.com/api/search/settings/fulltext" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/search/settings/global-search
Auth requiredsearch.manage

Update global search strategies

Sets which strategies are enabled for Cmd+K global search. Requires features: search.manage

Request body (application/json)

{
  "enabledStrategies": [
    "fulltext"
  ]
}

Responses

200Updated settings
Content-Type: application/json
{
  "ok": true,
  "enabledStrategies": [
    "fulltext"
  ]
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
500Internal error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/search/settings/global-search" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"enabledStrategies\": [
    \"fulltext\"
  ]
}"
GET/search/settings/vector-store
Auth requiredsearch.view

Get vector store configuration

Returns vector store configuration status. Requires features: search.view

Responses

200Vector store settings
Content-Type: application/json
{
  "currentDriver": "pgvector",
  "configured": true,
  "drivers": [
    {
      "id": "pgvector",
      "name": "string",
      "configured": true,
      "implemented": true,
      "envVars": [
        {
          "name": "string",
          "set": true,
          "hint": "string"
        }
      ]
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/search/settings/vector-store" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Currencies

Showing 14 of 14 endpoints
GET/currencies/currencies
Auth requiredcurrencies.view

List currencies

Returns a paginated collection of currencies scoped to the authenticated organization. Requires features: currencies.view

Parameters

NameInRequiredSchemaDescription
idqueryNoany
pagequeryNoany
pageSizequeryNoany
searchqueryNoany
sortFieldqueryNoany
sortDirqueryNoany
isBasequeryNoany
isActivequeryNoany
codequeryNoany
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated currencies
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "code": "string",
      "name": "string",
      "symbol": null,
      "decimalPlaces": 1,
      "thousandsSeparator": null,
      "decimalSeparator": null,
      "isBase": true,
      "isActive": true,
      "createdAt": null,
      "updatedAt": null,
      "organizationId": "string",
      "tenantId": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/currencies/currencies?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/currencies/currencies
Auth requiredcurrencies.manage

Create currency

Creates a new currency. Requires features: currencies.manage

Request body (application/json)

{
  "organizationId": "string",
  "tenantId": "string",
  "code": "string",
  "name": "string",
  "symbol": null,
  "thousandsSeparator": null,
  "decimalSeparator": null
}

Responses

201Currency created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://admin.getcovo.com/api/currencies/currencies" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"organizationId\": \"string\",
  \"tenantId\": \"string\",
  \"code\": \"string\",
  \"name\": \"string\",
  \"symbol\": null,
  \"thousandsSeparator\": null,
  \"decimalSeparator\": null
}"
PUT/currencies/currencies
Auth requiredcurrencies.manage

Update currency

Updates an existing currency by id. Requires features: currencies.manage

Request body (application/json)

{
  "id": "string",
  "symbol": null,
  "thousandsSeparator": null,
  "decimalSeparator": null
}

Responses

200Currency updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://admin.getcovo.com/api/currencies/currencies" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\",
  \"symbol\": null,
  \"thousandsSeparator\": null,
  \"decimalSeparator\": null
}"
DELETE/currencies/currencies
Auth requiredcurrencies.manage

Delete currency

Deletes a currency by id. Requires features: currencies.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Currency deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://admin.getcovo.com/api/currencies/currencies" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/currencies/currencies/options
Auth requiredcurrencies.view

List currency options

Returns currencies formatted for select inputs. Requires features: currencies.view

Parameters

NameInRequiredSchemaDescription
qqueryNoany
queryqueryNoany
searchqueryNoany
includeInactivequeryNoany
limitqueryNoany

Responses

200Option list
Content-Type: application/json
{
  "items": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}
400Invalid query
Content-Type: application/json
{
  "items": []
}

Example

curl -X GET "https://admin.getcovo.com/api/currencies/currencies/options?limit=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/currencies/exchange-rates
Auth requiredcurrencies.rates.view

List exchangerates

Returns a paginated collection of exchangerates scoped to the authenticated organization. Requires features: currencies.rates.view

Parameters

NameInRequiredSchemaDescription
idqueryNoany
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
fromCurrencyCodequeryNoany
toCurrencyCodequeryNoany
isActivequeryNoany
sourcequeryNoany
typequeryNoany
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated exchangerates
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "fromCurrencyCode": "string",
      "toCurrencyCode": "string",
      "rate": "string",
      "date": "string",
      "source": "string",
      "type": null,
      "isActive": true,
      "createdAt": null,
      "updatedAt": null,
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "tenantId": "00000000-0000-4000-8000-000000000000"
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/currencies/exchange-rates?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/currencies/exchange-rates
Auth requiredcurrencies.rates.manage

Create exchangerate

Creates a new exchange rate. Requires features: currencies.rates.manage

Request body (application/json)

{
  "organizationId": "string",
  "tenantId": "string",
  "fromCurrencyCode": "string",
  "toCurrencyCode": "string",
  "rate": "string",
  "type": null
}

Responses

201ExchangeRate created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://admin.getcovo.com/api/currencies/exchange-rates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"organizationId\": \"string\",
  \"tenantId\": \"string\",
  \"fromCurrencyCode\": \"string\",
  \"toCurrencyCode\": \"string\",
  \"rate\": \"string\",
  \"type\": null
}"
PUT/currencies/exchange-rates
Auth requiredcurrencies.rates.manage

Update exchangerate

Updates an existing exchange rate by id. Requires features: currencies.rates.manage

Request body (application/json)

{
  "id": "string",
  "type": null
}

Responses

200ExchangeRate updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://admin.getcovo.com/api/currencies/exchange-rates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\",
  \"type\": null
}"
DELETE/currencies/exchange-rates
Auth requiredcurrencies.rates.manage

Delete exchangerate

Deletes an exchange rate by id. Requires features: currencies.rates.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200ExchangeRate deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://admin.getcovo.com/api/currencies/exchange-rates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/currencies/fetch-configs

List currency fetch configurations

Returns all currency fetch configurations scoped to the authenticated organization.

Responses

200A list of currency fetch configurations
Content-Type: application/json
{
  "configs": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "provider": "string",
      "isEnabled": true,
      "syncTime": null,
      "lastSyncAt": null,
      "lastSyncStatus": null,
      "lastSyncMessage": null,
      "lastSyncCount": null,
      "config": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/currencies/fetch-configs" \
  -H "Accept: application/json"
POST/currencies/fetch-configs

Create currency fetch configuration

Creates a new currency fetch configuration.

Request body (application/json)

{
  "provider": "NBP",
  "isEnabled": false,
  "syncTime": null,
  "config": null
}

Responses

201Currency fetch configuration created successfully
Content-Type: application/json
{
  "config": {
    "id": "00000000-0000-4000-8000-000000000000",
    "organizationId": "00000000-0000-4000-8000-000000000000",
    "tenantId": "00000000-0000-4000-8000-000000000000",
    "provider": "string",
    "isEnabled": true,
    "syncTime": null,
    "lastSyncAt": null,
    "lastSyncStatus": null,
    "lastSyncMessage": null,
    "lastSyncCount": null,
    "config": null,
    "createdAt": "string",
    "updatedAt": "string"
  }
}
400Bad request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/currencies/fetch-configs" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"provider\": \"NBP\",
  \"isEnabled\": false,
  \"syncTime\": null,
  \"config\": null
}"
PUT/currencies/fetch-configs

Update currency fetch configuration

Updates an existing currency fetch configuration by id.

Request body (application/json)

{
  "syncTime": null,
  "config": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Currency fetch configuration updated successfully
Content-Type: application/json
{
  "config": {
    "id": "00000000-0000-4000-8000-000000000000",
    "organizationId": "00000000-0000-4000-8000-000000000000",
    "tenantId": "00000000-0000-4000-8000-000000000000",
    "provider": "string",
    "isEnabled": true,
    "syncTime": null,
    "lastSyncAt": null,
    "lastSyncStatus": null,
    "lastSyncMessage": null,
    "lastSyncCount": null,
    "config": null,
    "createdAt": "string",
    "updatedAt": "string"
  }
}
400Bad request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/currencies/fetch-configs" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"syncTime\": null,
  \"config\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/currencies/fetch-configs

Delete currency fetch configuration

Deletes a currency fetch configuration by id.

Parameters

NameInRequiredSchemaDescription
idqueryYesanyCurrency fetch configuration identifier to delete

Responses

200Currency fetch configuration deleted successfully
Content-Type: application/json
{
  "success": true
}
400Bad request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/currencies/fetch-configs?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
POST/currencies/fetch-rates

Fetch currency rates

Fetches currency exchange rates from configured providers for a specific date.

Request body (application/json)

{}

Responses

200Currency rates fetched successfully
Content-Type: application/json
{
  "totalFetched": 1,
  "byProvider": {
    "key": {
      "count": 1
    }
  },
  "errors": [
    "string"
  ]
}
400Bad request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "totalFetched": 1,
  "byProvider": {
    "key": {
      "count": 1
    }
  },
  "errors": [
    "string"
  ]
}

Example

curl -X POST "https://admin.getcovo.com/api/currencies/fetch-rates" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{}"

Events

Showing 2 of 2 endpoints
GET/events
Auth required

List declared events

Returns every declared event. Filters: category, module, excludeTriggerExcluded (default true).

Responses

200Declared events
Content-Type: application/json
{
  "data": [
    {
      "id": "string",
      "label": "string"
    }
  ],
  "total": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/events" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/events/stream
Auth required

GET /events/stream

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/events/stream" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Notifications

Showing 13 of 13 endpoints
GET/notifications
Auth required

List notifications

Returns a paginated collection of notifications.

Parameters

NameInRequiredSchemaDescription
statusqueryNoany
typequeryNoany
severityqueryNoany
sourceEntityTypequeryNoany
sourceEntityIdqueryNoany
sincequeryNoany
pagequeryNoany
pageSizequeryNoany
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated notifications
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "type": "string",
      "title": "string",
      "body": null,
      "titleKey": null,
      "bodyKey": null,
      "titleVariables": null,
      "bodyVariables": null,
      "icon": null,
      "severity": "string",
      "status": "string",
      "actions": [
        {
          "id": "string",
          "label": "string"
        }
      ],
      "sourceModule": null,
      "sourceEntityType": null,
      "sourceEntityId": null,
      "linkHref": null,
      "createdAt": "string",
      "readAt": null,
      "actionTaken": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/notifications?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications
Auth requirednotifications.create

Create notification

Creates a notification for a user. Requires features: notifications.create

Request body (application/json)

{
  "type": "string",
  "severity": "info",
  "recipientUserId": "00000000-0000-4000-8000-000000000000"
}

Responses

201Notification created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://admin.getcovo.com/api/notifications" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"type\": \"string\",
  \"severity\": \"info\",
  \"recipientUserId\": \"00000000-0000-4000-8000-000000000000\"
}"
POST/notifications/{id}/action
Auth required

POST /notifications/{id}/action

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/notifications/:id/action" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/{id}/dismiss
Auth required

PUT /notifications/{id}/dismiss

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://admin.getcovo.com/api/notifications/:id/dismiss" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/{id}/read
Auth required

PUT /notifications/{id}/read

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://admin.getcovo.com/api/notifications/:id/read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/{id}/restore
Auth required

PUT /notifications/{id}/restore

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://admin.getcovo.com/api/notifications/:id/restore" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/batch
Auth requirednotifications.create

POST /notifications/batch

Requires features: notifications.create

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/notifications/batch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/feature
Auth requirednotifications.create

POST /notifications/feature

Requires features: notifications.create

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/notifications/feature" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/mark-all-read
Auth required

PUT /notifications/mark-all-read

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://admin.getcovo.com/api/notifications/mark-all-read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/role
Auth requirednotifications.create

POST /notifications/role

Requires features: notifications.create

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/notifications/role" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/settings
Auth requirednotifications.manage

GET /notifications/settings

Requires features: notifications.manage

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/settings
Auth requirednotifications.manage

POST /notifications/settings

Requires features: notifications.manage

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/unread-count
Auth required

GET /notifications/unread-count

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/notifications/unread-count" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Scheduler

Showing 8 of 8 endpoints
GET/scheduler/jobs
Auth requiredscheduler.jobs.view

List scheduledjobs

Returns a paginated collection of scheduledjobs scoped to the authenticated organization. Requires features: scheduler.jobs.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
idqueryNoany
searchqueryNoany
scopeTypequeryNoany
isEnabledqueryYesany
sourceTypequeryNoany
sourceModulequeryNoany
sortqueryNoany
orderqueryNoany
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated scheduledjobs
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "description": null,
      "scopeType": "system",
      "organizationId": null,
      "tenantId": null,
      "scheduleType": "cron",
      "scheduleValue": "string",
      "timezone": "string",
      "targetType": "queue",
      "targetQueue": null,
      "targetCommand": null,
      "targetPayload": null,
      "requireFeature": null,
      "isEnabled": true,
      "lastRunAt": null,
      "nextRunAt": null,
      "sourceType": "user",
      "sourceModule": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/scheduler/jobs?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/scheduler/jobs
Auth requiredscheduler.jobs.manage

Create scheduledjob

Creates a new scheduled job with cron or interval-based scheduling. Requires features: scheduler.jobs.manage

Request body (application/json)

{
  "name": "string",
  "description": null,
  "scopeType": "system",
  "organizationId": null,
  "tenantId": null,
  "scheduleType": "cron",
  "scheduleValue": "string",
  "timezone": "UTC",
  "targetType": "queue",
  "targetQueue": null,
  "targetCommand": null,
  "targetPayload": null,
  "requireFeature": null,
  "isEnabled": true,
  "sourceType": "user",
  "sourceModule": null
}

Responses

201ScheduledJob created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://admin.getcovo.com/api/scheduler/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"description\": null,
  \"scopeType\": \"system\",
  \"organizationId\": null,
  \"tenantId\": null,
  \"scheduleType\": \"cron\",
  \"scheduleValue\": \"string\",
  \"timezone\": \"UTC\",
  \"targetType\": \"queue\",
  \"targetQueue\": null,
  \"targetCommand\": null,
  \"targetPayload\": null,
  \"requireFeature\": null,
  \"isEnabled\": true,
  \"sourceType\": \"user\",
  \"sourceModule\": null
}"
PUT/scheduler/jobs
Auth requiredscheduler.jobs.manage

Update scheduledjob

Updates an existing scheduled job by ID. Requires features: scheduler.jobs.manage

Request body (application/json)

{
  "id": "string",
  "description": null,
  "targetQueue": null,
  "targetCommand": null,
  "targetPayload": null,
  "requireFeature": null
}

Responses

200ScheduledJob updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://admin.getcovo.com/api/scheduler/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\",
  \"description\": null,
  \"targetQueue\": null,
  \"targetCommand\": null,
  \"targetPayload\": null,
  \"requireFeature\": null
}"
DELETE/scheduler/jobs
Auth requiredscheduler.jobs.manage

Delete scheduledjob

Deletes a scheduled job by ID. Requires features: scheduler.jobs.manage

Request body (application/json)

{
  "id": "string"
}

Responses

200ScheduledJob deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://admin.getcovo.com/api/scheduler/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\"
}"
GET/scheduler/jobs/{id}/executions

Get execution history for a schedule

Fetch recent executions from BullMQ for a scheduled job. Requires QUEUE_STRATEGY=async.

Parameters

NameInRequiredSchemaDescription
idpathYesany
pageSizequeryNoany

Responses

200Execution history
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "scheduleId": "00000000-0000-4000-8000-000000000000",
      "startedAt": "string",
      "finishedAt": null,
      "status": "running",
      "triggerType": "scheduled",
      "triggeredByUserId": null,
      "errorMessage": null,
      "errorStack": null,
      "durationMs": null,
      "queueJobId": "string",
      "queueName": "string",
      "attemptsMade": 1,
      "result": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1
}
400Local strategy not supported
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Access denied
Content-Type: application/json
{
  "error": "string"
}
404Schedule not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/scheduler/jobs/:id/executions?pageSize=20" \
  -H "Accept: application/json"
GET/scheduler/queue-jobs/{jobId}

Get BullMQ job details and logs

Fetch detailed information and logs for a queue job. Requires QUEUE_STRATEGY=async.

Parameters

NameInRequiredSchemaDescription
jobIdpathYesany
queuequeryYesany

Responses

200Job details and logs
Content-Type: application/json
{
  "id": "string",
  "name": "string",
  "state": "waiting",
  "progress": null,
  "returnvalue": null,
  "failedReason": null,
  "stacktrace": null,
  "attemptsMade": 1,
  "processedOn": null,
  "finishedOn": null,
  "logs": [
    "string"
  ]
}
400Invalid request or local strategy not supported
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Access denied
Content-Type: application/json
{
  "error": "string"
}
404Job not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/scheduler/queue-jobs/:jobId?queue=string" \
  -H "Accept: application/json"
GET/scheduler/targets

List available queues and commands

Returns all registered queue names (from module workers) and command IDs (from the command registry) that can be used as schedule targets.

Responses

200Available targets
Content-Type: application/json
{
  "queues": [
    {
      "value": "string",
      "label": "string"
    }
  ],
  "commands": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/scheduler/targets" \
  -H "Accept: application/json"
POST/scheduler/trigger

Manually trigger a schedule

Executes a scheduled job immediately, bypassing the scheduled time. Only works with async queue strategy.

Request body (application/json)

{
  "id": "string"
}

Responses

200Schedule triggered successfully
Content-Type: application/json
{
  "ok": true,
  "jobId": "string",
  "message": "string"
}
400Invalid request or local strategy not supported
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Access denied
Content-Type: application/json
{
  "error": "string"
}
404Schedule not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/scheduler/trigger" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\"
}"

Health

Showing 2 of 2 endpoints
GET/health/live

Liveness probe

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/health/live" \
  -H "Accept: application/json"
GET/health/ready

Readiness probe

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/health/ready" \
  -H "Accept: application/json"

Wallet

Showing 5 of 5 endpoints
POST/wallet/admin/workers/wallet-retention
Auth requiredwallet.admin.run_retention

Run wallet-retention worker inline

Executes the wallet retention purge worker synchronously. Hard-deletes wallets and their ledger (transactions, credit batches, idempotency keys, lifetime savings) for users past their account_deletion_waivers.purge_after date. Used for integration tests and operational diagnostics. Requires features: wallet.admin.run_retention

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/wallet/admin/workers/wallet-retention" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/me/wallet/auto-refill
Auth requiredwallet.balance.view

Get auto-refill configuration

Returns the current user auto-refill configuration and monthly-spent counter derived from succeeded auto-refill payments since the start of the current UTC month. Requires features: wallet.balance.view

Responses

200Auto-refill configuration
Content-Type: application/json
{
  "enabled": true,
  "amountEuroCents": null,
  "thresholdEuroCents": null,
  "monthlyCapEuroCents": null,
  "monthlySpentEuroCents": 1,
  "pausedAt": null,
  "pausedReason": null
}
404Consumer profile not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/me/wallet/auto-refill" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/wallet/me/wallet/auto-refill
Auth requiredwallet.balance.view

Update auto-refill configuration

Updates the current user auto-refill configuration. Setting enabled=true implicitly clears pause. Requires features: wallet.balance.view

Request body (application/json)

{
  "enabled": true,
  "amountEuroCents": null,
  "thresholdEuroCents": null,
  "monthlyCapEuroCents": null
}

Responses

200Auto-refill configuration updated
Content-Type: application/json
{
  "enabled": true,
  "amountEuroCents": null,
  "thresholdEuroCents": null,
  "monthlyCapEuroCents": null,
  "monthlySpentEuroCents": 1,
  "pausedAt": null,
  "pausedReason": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Consumer profile not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/wallet/me/wallet/auto-refill" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"enabled\": true,
  \"amountEuroCents\": null,
  \"thresholdEuroCents\": null,
  \"monthlyCapEuroCents\": null
}"
GET/wallet/me/wallets
Auth requiredwallet.balance.view

Get current user wallets

Returns standard, bonus, and combined virtual wallet with balances. Requires features: wallet.balance.view

Responses

200User wallets
Content-Type: application/json
{
  "wallets": [
    {
      "id": null,
      "type": "standard",
      "balance": {
        "amountInMinorUnits": 1,
        "currency": "string"
      }
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/me/wallets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/me/wallets/transactions
Auth requiredwallet.transactions.view

Get transaction history

Returns paginated transaction history across all wallets, sorted by date descending. Requires features: wallet.transactions.view

Parameters

NameInRequiredSchemaDescription
limitqueryNoany
offsetqueryNoany
typequeryNoany
walletTypequeryNoany

Responses

200Transaction list
Content-Type: application/json
{
  "transactions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "walletId": "00000000-0000-4000-8000-000000000000",
      "walletType": "standard",
      "type": "credit",
      "amount": {
        "amountInMinorUnits": 1,
        "currency": "string"
      },
      "description": "string",
      "referenceType": "top_up",
      "referenceId": null,
      "countryCodes": null,
      "usageBytes": null,
      "invoiceId": null,
      "creditNoteId": null,
      "createdAt": "string"
    }
  ],
  "total": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/me/wallets/transactions?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Payments

Showing 13 of 13 endpoints
POST/payments/admin/workers/payment-device-trust-redaction
Auth requiredpayments.admin.run_retention

Run payment-device-trust-redaction worker inline

Executes the payment device-trust redaction worker synchronously. Nulls client_ip, client_user_agent, client_device_id, and client_app_version on Payment rows for users whose account_deletion_waivers passed the § 195 BGB 3-year mark, keeping consent_version and financial columns. Used for integration tests and operational diagnostics. Requires features: payments.admin.run_retention

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/admin/workers/payment-device-trust-redaction" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/payments/admin/workers/stripe-api-calls-retention
Auth requiredpayments.admin.run_retention

Run stripe-api-calls-retention worker inline

Executes the Stripe API call retention sweep worker synchronously. Hard-deletes stripe_api_calls rows older than 90 days. Used for integration tests and operational diagnostics. Requires features: payments.admin.run_retention

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/admin/workers/stripe-api-calls-retention" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/payments/admin/workers/stripe-webhook-events-retention
Auth requiredpayments.admin.run_retention

Run stripe-webhook-events-retention worker inline

Executes the Stripe webhook event retention sweep worker synchronously. Hard-deletes terminal stripe_webhook_events rows older than 1 year. Used for integration tests and operational diagnostics. Requires features: payments.admin.run_retention

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/admin/workers/stripe-webhook-events-retention" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/payments/admin/workers/user-financial-data-retention
Auth requiredpayments.admin.run_retention

Run user-financial-data-retention worker inline

Executes the user financial data retention purge worker synchronously. Hard-deletes Payment, Invoice, and StripeCustomer rows for users past their account_deletion_waivers.purge_after date. Used for integration tests and operational diagnostics. Requires features: payments.admin.run_retention

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/admin/workers/user-financial-data-retention" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/payments/me/credit-notes/{id}/download
Auth requiredpayments.invoices.view

Download credit note PDF

Redirects (302) to the Stripe-hosted PDF for the authenticated user's credit note. Scoped to `user_id = auth.sub` and the caller's tenant/organization. Returns 404 when the credit note does not belong to the caller or the PDF has not been finalised yet. Requires features: payments.invoices.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Success response
Content-Type: application/json
"string"
302Redirect to the Stripe-hosted credit note PDF
Content-Type: application/json
"string"
400Invalid id
Content-Type: application/json
{
  "error": "string"
}
404Credit note or PDF not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load credit note
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/me/credit-notes/00000000-0000-4000-8000-000000000000/download" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/payments/me/customer-session
Auth requiredpayments.method.manage

Create a Customer Session for managing saved payment methods

Creates a Stripe CustomerSession with the customer_sheet component enabled. Used by the mobile app to render the Stripe Customer Sheet for adding, listing and removing saved cards. Requires features: payments.method.manage

Responses

200CustomerSession created
Content-Type: application/json
{
  "clientSecret": "string",
  "customerId": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/me/customer-session" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/payments/me/invoices
Auth requiredpayments.invoices.view

List the caller's invoices

Returns Stripe invoices for the authenticated user, newest first. Scoped to `user_id = auth.sub` and the caller's tenant/organization. Supports optional `status` filter (Stripe statuses: draft, open, paid, uncollectible, void) and `limit`/`offset` pagination. Requires features: payments.invoices.view

Parameters

NameInRequiredSchemaDescription
statusqueryNoany
limitqueryNoany
offsetqueryNoany

Responses

200Caller's invoices
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "stripeInvoiceId": "string",
      "status": "draft",
      "amount": {
        "amountInMinorUnits": 1,
        "currency": "string"
      },
      "invoiceNumber": null,
      "hostedInvoiceUrl": null,
      "invoicePdfUrl": null,
      "reverseCharge": true,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
500Failed to load invoices
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/me/invoices?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/payments/me/invoices/{id}/download
Auth requiredpayments.invoices.view

Download invoice PDF

Redirects (302) to the Stripe-hosted PDF for the authenticated user's invoice. Scoped to `user_id = auth.sub` and the caller's tenant/organization. Returns 404 when the invoice does not belong to the caller or the PDF has not been finalised yet. Requires features: payments.invoices.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Success response
Content-Type: application/json
"string"
302Redirect to the Stripe-hosted invoice PDF
Content-Type: application/json
"string"
400Invalid id
Content-Type: application/json
{
  "error": "string"
}
404Invoice or PDF not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load invoice
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/me/invoices/00000000-0000-4000-8000-000000000000/download" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/payments/me/payments/{id}
Auth requiredpayments.status.view

Get payment status and details

Returns payment details for the authenticated user. Requires features: payments.status.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Payment details
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "pending",
  "amount": null,
  "originalAmount": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "paymentType": "top_up",
  "description": "string",
  "failureReason": null,
  "createdAt": "string"
}
400Invalid id
Content-Type: application/json
{
  "error": "string"
}
404Not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load payment
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/me/payments/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/payments/me/payments/methods/availability
Auth requiredpayments.method.manage

Whether the user has a usable off-session payment method

Returns whether the authenticated user has at least one reusable card (allow_redisplay='always') on their Stripe customer that is usable for off-session charges - i.e. not expired. Returns false when the user has no Stripe customer yet. Lets the mobile app decide whether to offer features that depend on off-session billing (auto-refill, network turbo). Requires features: payments.method.manage

Responses

200Off-session payment method availability
Content-Type: application/json
{
  "hasOffSessionPaymentMethod": true
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/me/payments/methods/availability" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/payments/me/payments/top-up
Auth requiredpayments.topup.create

Create a PaymentIntent for wallet top-up

Creates a Stripe PaymentIntent (backed by a finalized Stripe Invoice) and returns the client secret along with the customer id and a fresh Stripe CustomerSession client secret scoped to the `mobile_payment_element` component. The mobile app passes those three values to the Stripe Mobile SDK Payment Sheet (`paymentIntentClientSecret` + `customerId` + `customerSessionClientSecret`). Payment Sheet presents the saved cards already on the Stripe customer, lets the user add a new one with an optional "Save this card for future use" checkbox (enabled via the CustomerSession `mobile_payment_element.features.payment_method_save` flag — the mobile SDK only reads `mobile_payment_element`, not the web `payment_element` component), handles 3DS, Apple Pay and Google Pay, and confirms the PaymentIntent. When the user ticks the checkbox the new PaymentMethod is attached with `allow_redisplay=always` and the PaymentIntent gets `setup_future_usage` so it stays reusable for auto-refill. The backend does not pre-select a payment method, does not set `setup_future_usage` on the PaymentIntent directly, and does not charge off-session — all of that is delegated to Payment Sheet. Requires `stripe-react-native` >= 0.56.0 (CustomerSession support for Payment Sheet went GA there). `amount.amountInMinorUnits` is expressed in the minor units of `amount.currency` (e.g. cents for EUR, kuruş for TRY). Minimum top-up is €5.00 and maximum is €10,000.00 (both compared against the EUR equivalent for non-EUR requests). `idempotencyKey` is optional; reuse the same UUID to safely retry the same logical top-up. Request example: ```json { "amount": { "amountInMinorUnits": 500, "currency": "EUR" }, "idempotencyKey": "00000000-0000-4000-8000-000000000000" } ``` Chargeback-evidence headers (optional, persisted on the Payment row for 10-year financial retention and used to defend disputes after a possible account deletion): - Client IP — resolved via the shared `getClientIp` helper, which respects `TRUST_PROXY_DEPTH`. With depth=0 (no trusted proxies) it reads `X-Real-IP`; with depth≥1 it picks the appropriate entry from `X-Forwarded-For`. Stored as `client_ip`. - `User-Agent` — stored as `client_user_agent`. - `X-Covo-Device-Id` — stable per-install device id supplied by the mobile app; stored as `client_device_id`. - `X-Covo-App-Version` — mobile app version; stored as `client_app_version`. Requires features: payments.topup.create

Request body (application/json)

{
  "amount": {
    "amountInMinorUnits": 1,
    "currency": "string"
  }
}

Responses

200PaymentIntent created
Content-Type: application/json
{
  "baseAmount": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "bonusAmount": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "bonusPercent": 1,
  "totalCredit": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "estimatedDisplayTotalCredit": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "clientSecret": "string",
  "paymentIntentId": "string",
  "customerId": "string",
  "customerSessionClientSecret": "string"
}
400Validation error
Content-Type: application/json
{
  "error": "string"
}
402Card charge failed before Payment Sheet could run (e.g. Stripe rejected the invoice/PaymentIntent creation). Body includes the Stripe failure message, decline code and PaymentIntent id when available.
Content-Type: application/json
{
  "error": "string",
  "message": "string",
  "code": null,
  "paymentIntentId": null
}
422Top-up cannot proceed because the consumer billing country is missing or no tax rate is configured for it. Body includes the reason and the rejected country (when known).
Content-Type: application/json
{
  "error": "string",
  "reason": "billing-country-missing",
  "country": null
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/me/payments/top-up" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"amount\": {
    \"amountInMinorUnits\": 1,
    \"currency\": \"string\"
  }
}"
GET/payments/me/payments/top-up/preview
Auth requiredpayments.topup.create

Preview wallet top-up with volume bonus

Returns the volume bonus the user would receive for a given top-up amount. For non-EUR amounts, the EUR-equivalent is computed using the latest Stripe FX rate; the actual bonus on payment success uses the settled EUR amount and may differ by a few cents. Requires features: payments.topup.create

Parameters

NameInRequiredSchemaDescription
amountqueryYesany
currencyqueryYesany

Responses

200Top-up preview
Content-Type: application/json
{
  "baseAmount": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "bonusAmount": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "bonusPercent": 1,
  "totalCredit": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "estimatedDisplayTotalCredit": {
    "amountInMinorUnits": 1,
    "currency": "string"
  }
}
400Validation error
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/me/payments/top-up/preview?amount=1&currency=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/payments/me/setup-intent
Auth requiredpayments.method.manage

Create a SetupIntent for saving a card

Creates a Stripe SetupIntent for saving a payment method without charging. Used for setting up auto-refill. Requires features: payments.method.manage

Responses

200SetupIntent created
Content-Type: application/json
{
  "clientSecret": "string",
  "setupIntentId": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/me/setup-intent" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

eSIMs

Showing 20 of 37 endpoints
POST/esims
Auth requiredesims.create

Create eSIM for authenticated consumer

Creates a new eSIM for the authenticated consumer. Provisions via 1Global. Requires features: esims.create

Request body (application/json)

{}

Responses

201eSIM created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "pending"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
402Insufficient wallet balance
Content-Type: application/json
{
  "error": "string"
}
404Consumer profile not found
Content-Type: application/json
{
  "error": "string"
}
409Consumer already has an eSIM
Content-Type: application/json
{
  "error": "string"
}
422Home country code not set on consumer profile
Content-Type: application/json
{
  "error": "string"
}
5021Global API error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
GET/esims/{id}
Auth requiredesims.view

Get eSIM details

Returns full eSIM details including activation info, QR code, and universal install links. `installLinks.ios` works on iOS 17.4+; `installLinks.android` works on Android 10+. Both are null until 1Global has provided both `matching_id` and `smdp_address`. Requires features: esims.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200eSIM details
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "iccid": null,
  "qrCodeUrl": null,
  "installLinks": {
    "ios": null,
    "android": null
  },
  "activationCode": null,
  "matchingId": null,
  "status": "pending",
  "phoneNumber": null,
  "countryCode": null,
  "usedBytes": 1,
  "totalBytes": 1,
  "dataLimitBytes": null,
  "expiresAt": null,
  "disableEsimInHomeZone": true,
  "isThrottled": true,
  "isInstalled": true
}
400Invalid ID
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/esims/{id}/country
Auth requiredesims.set-country

Set the eSIM's current country and rebuild the addon stack

Updates Esim.currentCountryCode (and lastCountryAt) for the authenticated user's eSIM, then runs syncDataLimit so the addon stack is rebuilt for the new country's pricing. Only the eSIM owner can call this endpoint. Requires features: esims.set-country

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "countryCode": "string"
}

Responses

200Country updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "countryCode": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found or not owned by the caller
Content-Type: application/json
{
  "error": "string"
}
422Country is not in the pricing table
Content-Type: application/json
{
  "error": "string"
}
500Server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/00000000-0000-4000-8000-000000000000/country" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"countryCode\": \"string\"
}"
PUT/esims/{id}/home-zone
Auth requiredesims.home-zone

Enable/disable home zone for eSIM

Toggles the home zone setting for the consumer's eSIM. Only the eSIM owner can update this. Requires features: esims.home-zone

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "disableEsimInHomeZone": true
}

Responses

200Home zone updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "disableEsimInHomeZone": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/esims/00000000-0000-4000-8000-000000000000/home-zone" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"disableEsimInHomeZone\": true
}"
GET/esims/{id}/usage
Auth requiredesims.usage

Get eSIM usage

Returns detailed usage data with 7-day timeline for charts. Requires features: esims.usage

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200eSIM usage data
Content-Type: application/json
{
  "usedBytes": 1,
  "totalBytes": 1,
  "dataLimitBytes": null,
  "usagePercent": null,
  "timeline": [
    {
      "date": "string",
      "usageBytes": 1,
      "totalBytes": 1
    }
  ]
}
400Invalid ID
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/00000000-0000-4000-8000-000000000000/usage" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/esims/admin
Auth requiredesims.admin.list

List eSIMs

Returns eSIMs with pagination, search, and sorting. The search query matches (partial, case-insensitive) the owner email, eSIM name, ICCID and matching id (via the encrypted search token index), plus the 1Global order id, subscription id, subscriber id and account id (via direct lookup). Pass id query param to get a single eSIM. Each item includes universal `installLinks`: `installLinks.ios` requires iOS 17.4+ and `installLinks.android` requires Android 10+; both are null until 1Global has provided both `matching_id` and `smdp_address`. Requires features: esims.admin.list

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
searchqueryNoany
idqueryNoany
consumerIdqueryNoany

Responses

200eSIM list
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "status": "pending",
      "iccid": null,
      "consumerProfileId": "00000000-0000-4000-8000-000000000000",
      "consumerEmail": null,
      "qrCodeUrl": null,
      "installLinks": {
        "ios": null,
        "android": null
      },
      "oneGlobalOrderId": null,
      "oneGlobalSubscriptionId": null,
      "isThrottled": true,
      "isInstalled": true,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/admin?page=1&pageSize=50&sortField=createdAt&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/esims/admin
Auth requiredesims.admin.update

Update eSIM

Updates an eSIM name. Requires features: esims.admin.update

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string"
}

Responses

200eSIM updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/esims/admin" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"name\": \"string\"
}"
POST/esims/admin/__test__/age-snapshots
Auth requiredesims.admin.update

Backdate usage snapshot created_at

Test-mode admin utility used by integration tests to backdate snapshot timestamps so the hourly worker re-processes them. Returns 404 unless ONE_GLOBAL_TEST_MODE=true. Requires features: esims.admin.update

Request body (application/json)

{
  "esimId": "00000000-0000-4000-8000-000000000000"
}

Responses

200Snapshots aged
Content-Type: application/json
{
  "ok": true,
  "updated": 1
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Not found (test mode disabled)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/admin/__test__/age-snapshots" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"esimId\": \"00000000-0000-4000-8000-000000000000\"
}"
POST/esims/admin/__test__/one-global-spent
Auth requiredesims.admin.update

Set or clear 1Global test-mode spent override

Test-mode admin utility used by integration tests to deterministically seed the bytes 1Global reports as spent for a given subscriptionId. Returns 404 unless ONE_GLOBAL_TEST_MODE=true. Requires features: esims.admin.update

Request body (application/json)

{
  "subscriptionId": "string",
  "spentBytes": 1
}

Responses

200Override applied
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Not found (test mode disabled)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/admin/__test__/one-global-spent" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"subscriptionId\": \"string\",
  \"spentBytes\": 1
}"
POST/esims/admin/__test__/refunds-reports
Auth requiredesims.refunds-report.view

Drive refunds-report flows for integration tests

Seeds refunded payments, generates/escalates a refunds report with an injected clock, or backdates a report. Returns 404 unless ONE_GLOBAL_TEST_MODE=true. Requires features: esims.refunds-report.view

Request body (application/json)

{
  "action": "seed-payment",
  "amountEuroCents": 1,
  "amountRefundedEuroCents": 1,
  "refundedAt": "string",
  "status": "refunded"
}

Responses

200Action result
Content-Type: application/json
{}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Not found (test mode disabled)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/admin/__test__/refunds-reports" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"action\": \"seed-payment\",
  \"amountEuroCents\": 1,
  \"amountRefundedEuroCents\": 1,
  \"refundedAt\": \"string\",
  \"status\": \"refunded\"
}"
DELETE/esims/admin/__test__/refunds-reports
Auth requiredesims.refunds-report.view

Clean up seeded payments and reports

Deletes the given payments/reports. Returns 404 unless ONE_GLOBAL_TEST_MODE=true. Requires features: esims.refunds-report.view

Request body (application/json)

{}

Responses

200Deleted
Content-Type: application/json
{}
404Not found (test mode disabled)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/esims/admin/__test__/refunds-reports" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
GET/esims/admin/__test__/snapshots
Auth requiredesims.admin.list

List usage snapshots for an eSIM

Test-mode admin utility used by integration tests to inspect snapshot state. Returns 404 unless ONE_GLOBAL_TEST_MODE=true. Requires features: esims.admin.list

Parameters

NameInRequiredSchemaDescription
esimIdqueryYesany

Responses

200Snapshot list
Content-Type: application/json
{
  "snapshots": [
    {
      "id": "string",
      "esimId": "string",
      "initialBytes": "string",
      "spentBytes": "string",
      "remainingBytes": "string",
      "countryCode": null,
      "source": "string",
      "billedAt": null,
      "previousUsageSnapshotId": null,
      "standardDebitTransactionId": null,
      "bonusDebitTransactionId": null,
      "createdAt": "string"
    }
  ]
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
404Not found (test mode disabled)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/admin/__test__/snapshots?esimId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/esims/admin/{id}
Auth requiredesims.admin.view

Get eSIM detail

Returns full eSIM state including the SM-DP+ address and universal install links (`installLinks.ios` requires iOS 17.4+; `installLinks.android` requires Android 10+; both null until 1Global has provided both `matching_id` and `smdp_address`), the eSIM consumer, the billing user (which may differ from the consumer for family plans) along with their wallets, auto-refill state, and spending cap, the addon stack summary, data products, and recent usage snapshots. Pass `includeDropped=true` to include data products that 1Global has stopped reporting (default hides them). Requires features: esims.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany
includeDroppedqueryNoany

Responses

200eSIM detail
Content-Type: application/json
{
  "esim": {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string",
    "status": "pending",
    "iccid": null,
    "matchingId": null,
    "smdpAddress": null,
    "qrCodeUrl": null,
    "installLinks": {
      "ios": null,
      "android": null
    },
    "disableEsimInHomeZone": true,
    "isThrottled": true,
    "isInstalled": true,
    "currentCountryCode": null,
    "lastLifecycleAt": null,
    "lastUsageAt": null,
    "lastCountryAt": null,
    "lastInstallationAt": null,
    "oneGlobalOrderId": null,
    "oneGlobalSubscriptionId": null,
    "consumerProfileId": "00000000-0000-4000-8000-000000000000",
    "createdAt": "string",
    "updatedAt": "string"
  },
  "consumer": {
    "id": "00000000-0000-4000-8000-000000000000",
    "userId": "00000000-0000-4000-8000-000000000000",
    "email": null,
    "fullName": null,
    "firstName": null,
    "lastName": null,
    "phone": null,
    "languageCode": null,
    "displayCurrency": null,
    "homeCountryCode": null,
    "travelProfile": null,
    "addressLine1": null,
    "addressLine2": null,
    "addressCity": null,
    "addressState": null,
    "addressCountry": null,
    "addressPostalCode": null,
    "birthDate": null
  },
  "billing": {
    "userId": "00000000-0000-4000-8000-000000000000",
    "email": null,
    "fullName": null,
    "isSelfBilled": true,
    "billingUserMissing": true,
    "consumerProfileId": null,
    "spendingCapEuroCents": null,
    "autoRefill": {
      "enabled": true,
      "amountEuroCents": null,
      "thresholdEuroCents": null,
      "monthlyCapEuroCents": null,
      "pausedAt": null,
      "pausedReason": null
    },
    "wallets": {
      "standard": null,
      "bonus": null
    }
  },
  "oneGlobalAccountId": null,
  "oneGlobalSubscriberId": null,
  "addonStackSummary": {
    "activeCount": 1,
    "pendingCount": 1,
    "depletedCount": 1,
    "cancelledCount": 1,
    "failedCount": 1,
    "expiredCount": 1,
    "terminatedCount": 1,
    "totalActiveBytes": 1,
    "totalLeftCapacityBytes": 1,
    "actualTotalAllowanceBytes": null,
    "actualLeftAllowanceBytes": null,
    "spentBytes": 1,
    "lastAddedAt": null
  },
  "dataProducts": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "status": "pending",
      "dropped": true,
      "oneGlobalProductId": null,
      "oneGlobalOrderId": null,
      "oneGlobalOfferingId": null,
      "offeringName": null,
      "offeringCountries": null,
      "dataBytes": 1,
      "lastWebhookEventAt": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "usageSnapshots": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "source": "api",
      "countryCode": null,
      "initialBytes": 1,
      "spentBytes": 1,
      "remainingBytes": 1,
      "billedAt": null,
      "createdAt": "string"
    }
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000?includeDropped=false" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/esims/admin/{id}/calls
Auth requiredesims.admin.view

List 1Global API calls related to an eSIM

Returns paginated 1Global API calls (outbound + inbound webhooks) correlated to a specific eSIM via direct esim_id, order, subscription, ICCID, matching id, or pre-creation account/subscriber events on the consumer profile. When `oneGlobalOrderId` or `oneGlobalProductId` query params are supplied, results are instead scoped to a single data product (matching either identifier) instead of the eSIM-wide correlation. Returns 404 if no data product on this eSIM matches the supplied identifiers. The `eventTypes` query param is repeatable and filters rows to `eventType IN (...)`. The response also returns `availableEventTypes` — the distinct, alphabetically sorted set of event types observed within the scope (ignoring the active `eventTypes` filter) so callers can render a stable filter dropdown. Requires features: esims.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany
pagequeryNoany
pageSizequeryNoany
directionqueryNoany
handlingStatusqueryNoany
eventTypesqueryNoany
fromqueryNoany
toqueryNoany
oneGlobalOrderIdqueryNoany
oneGlobalProductIdqueryNoany

Responses

2001Global API calls
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "direction": "outbound",
      "handlingStatus": null,
      "method": "string",
      "endpoint": "string",
      "eventType": null,
      "statusCode": null,
      "durationMs": null,
      "idempotencyKey": null,
      "externalEventId": null,
      "errorMessage": null,
      "esimId": null,
      "consumerProfileId": null,
      "oneGlobalOrderId": null,
      "oneGlobalSubscriptionId": null,
      "oneGlobalProductId": null,
      "trigger": null,
      "triggers": null,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1,
  "availableEventTypes": [
    "string"
  ]
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000/calls?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/esims/admin/{id}/calls/{callId}
Auth requiredesims.admin.view

Get a single 1Global API call belonging to an eSIM

Returns the full payload (request/response headers and bodies) for a single OneGlobalApiCall that correlates to the specified eSIM via direct esim_id, order, subscription, ICCID, matching id, or a pre-creation account/subscriber event on the consumer profile. Returns 404 if the call does not exist or is not correlated to this eSIM. Requires features: esims.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany
callIdpathYesany

Responses

2001Global API call detail
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "direction": "outbound",
  "handlingStatus": null,
  "method": "string",
  "endpoint": "string",
  "eventType": null,
  "statusCode": null,
  "durationMs": null,
  "idempotencyKey": null,
  "externalEventId": null,
  "errorMessage": null,
  "esimId": null,
  "consumerProfileId": null,
  "oneGlobalOrderId": null,
  "oneGlobalSubscriptionId": null,
  "oneGlobalProductId": null,
  "trigger": null,
  "triggers": null,
  "createdAt": "string",
  "requestHeaders": null,
  "requestBody": null,
  "responseHeaders": null,
  "responseBody": null
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404eSIM or call not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000/calls/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/esims/admin/{id}/country
Auth requiredesims.admin.set-country

Manually set eSIM's current country and rebuild the addon stack

Updates Esim.currentCountryCode (and lastCountryAt) for the eSIM, then runs syncDataLimit so the addon stack is rebuilt for the new country's pricing. Recorded in the action log AND surfaced in the eSIM's 1Global activity log as an admin_action entry. Requires features: esims.admin.set-country

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "countryCode": "string"
}

Responses

200Country updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "countryCode": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}
422Country is not in the pricing table
Content-Type: application/json
{
  "error": "string"
}
500Server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000/country" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"countryCode\": \"string\"
}"
POST/esims/admin/{id}/country-recheck
Auth requiredesims.admin.country-recheck

Send a country-recheck push (admin/QA tool)

Fires a country-recheck push at the eSIM owner on demand. `variant: 'silent'` sends a data-only push that wakes the app to silently re-detect location; `variant: 'visible'` sends a user-visible push asking the traveller to open the app. Both bypass per-user opt-out and frequency caps (the types are declared nonOptOut). Exercises the same send path the sensor-addon detection flow will use. For the silent variant the response carries per-device delivery counts; for the visible variant it carries the created in-app notification id. Requires features: esims.admin.country-recheck

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "variant": "silent"
}

Responses

200Country-recheck push dispatched
Content-Type: application/json
{
  "ok": true,
  "variant": "silent",
  "userId": "00000000-0000-4000-8000-000000000000",
  "notificationId": null,
  "delivery": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}
500Server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000/country-recheck" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"variant\": \"silent\"
}"
POST/esims/admin/{id}/data-limit
Auth requiredesims.admin.set-data-limit

Manually set eSIM's data limit by triggering an addon-stack rebuild

Calls syncDataLimit with an admin-supplied target (in bytes) instead of the wallet-derived target. The result lives in the addon stack: 1Global products are purchased and/or cancelled to match. The action is recorded in the action log AND in the eSIM's 1Global activity log as an admin_action entry. Requires features: esims.admin.set-data-limit

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "targetBytes": 1
}

Responses

200Data limit synced
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "targetBytes": 1
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}
422eSIM has no 1Global subscription or current country
Content-Type: application/json
{
  "error": "string"
}
500Server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000/data-limit" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"targetBytes\": 1
}"
POST/esims/admin/{id}/fake-usage
Auth requiredesims.admin.fake-usage

Simulate data consumption on an eSIM (admin/QA tool)

Simulates usage in a chosen country by emitting the same internal events the 1Global threshold/depleted webhooks emit, so the result is indistinguishable from real usage. Targets the data product real usage in that country would consume: the oldest active addon (first in the depletion order) whose offering covers the country. If no such product exists, nothing happens and the response carries `applied: false` with a `reason`. Defaults the country to the eSIM's current country when omitted. Builds the synthetic balance from local state (latest usage snapshot, falling back to the product's allowance) and never reads from 1Global. When usage IS applied the downstream effects are real: a real wallet debit for the consumed bytes, cap-threshold notifications, and — when the amount consumes the product's full remaining balance — a real `product.depleted` flow that marks the product depleted and provisions the next addon via live 1Global calls. The usage snapshot is created asynchronously by the subscriber, so it is not returned here. Requires features: esims.admin.fake-usage

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "amountGb": 1
}

Responses

200Fake usage event emitted (applied: true), or a no-op when no covering product exists (applied: false)
Content-Type: application/json
{
  "ok": true,
  "applied": true,
  "reason": null,
  "countryCode": null,
  "productId": null,
  "amountGb": 1,
  "depleted": true,
  "balance": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}
500Server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000/fake-usage" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"amountGb\": 1
}"
PUT/esims/admin/{id}/home-zone
Auth requiredesims.admin.home-zone

Admin override of an eSIM's home zone status

Toggles Esim.disableEsimInHomeZone for the eSIM, regardless of consumer ownership. When disabling while the eSIM is currently roaming in the consumer's home country, the active addon stack is cancelled via 1Global. Recorded as an admin_action entry in the eSIM's 1Global activity log. Requires features: esims.admin.home-zone

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "disableEsimInHomeZone": true
}

Responses

200Home zone updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "disableEsimInHomeZone": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404eSIM not found
Content-Type: application/json
{
  "error": "string"
}
500Server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/esims/admin/00000000-0000-4000-8000-000000000000/home-zone" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"disableEsimInHomeZone\": true
}"

Tax Rates

Showing 5 of 5 endpoints
GET/tax_rates/admin/tax-rates
Auth requiredtax_rates.admin.list

List tax rates (admin)

Returns the tax rate catalog with pagination and search by country, subdivision, postal code pattern, display name, or jurisdiction. Requires features: tax_rates.admin.list

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
searchqueryNoany

Responses

200Tax rate list
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "country": "string",
      "subdivision": null,
      "postalCodePattern": null,
      "percentage": 1,
      "displayName": "string",
      "jurisdiction": null,
      "validFrom": "string",
      "validTo": null,
      "inclusive": true,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/tax_rates/admin/tax-rates?page=1&pageSize=50&sortField=country&sortDir=asc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/tax_rates/admin/tax-rates
Auth requiredtax_rates.admin.create

Create tax rate

Creates a new tax rate in the catalog. Action is logged and reversible via undo (soft-deletes the new row). Requires features: tax_rates.admin.create

Request body (application/json)

{
  "country": "string",
  "subdivision": null,
  "postalCodePattern": null,
  "percentage": 1,
  "displayName": "string",
  "jurisdiction": null,
  "validFrom": "string",
  "validTo": null,
  "inclusive": false
}

Responses

201Tax rate created
Content-Type: application/json
{
  "ok": true,
  "id": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/tax_rates/admin/tax-rates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"country\": \"string\",
  \"subdivision\": null,
  \"postalCodePattern\": null,
  \"percentage\": 1,
  \"displayName\": \"string\",
  \"jurisdiction\": null,
  \"validFrom\": \"string\",
  \"validTo\": null,
  \"inclusive\": false
}"
PUT/tax_rates/admin/tax-rates
Auth requiredtax_rates.admin.update

Update tax rate

Updates an existing tax rate identified by `id` in the body. At least one mutable field must be provided. Action is logged and reversible via undo. Requires features: tax_rates.admin.update

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "subdivision": null,
  "postalCodePattern": null,
  "jurisdiction": null,
  "validTo": null
}

Responses

200Tax rate updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Tax rate not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/tax_rates/admin/tax-rates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"subdivision\": null,
  \"postalCodePattern\": null,
  \"jurisdiction\": null,
  \"validTo\": null
}"
DELETE/tax_rates/admin/tax-rates
Auth requiredtax_rates.admin.delete

Delete tax rate

Soft-deletes a tax rate by `id` (passed as the `id` query param). Action is logged and reversible via undo. Requires features: tax_rates.admin.delete

Parameters

NameInRequiredSchemaDescription
idqueryYesany

Responses

200Tax rate deleted
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Tax rate not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/tax_rates/admin/tax-rates?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/tax_rates/admin/tax-rates/{id}
Auth requiredtax_rates.admin.update

Get a tax rate by id (admin)

Returns a single tax rate by its UUID. Used by the admin edit page to load a row without scanning the full catalog. Requires features: tax_rates.admin.update

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Tax rate
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "country": "string",
  "subdivision": null,
  "postalCodePattern": null,
  "percentage": 1,
  "displayName": "string",
  "jurisdiction": null,
  "validFrom": "string",
  "validTo": null,
  "inclusive": true,
  "createdAt": "string",
  "updatedAt": "string"
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Tax rate not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/tax_rates/admin/tax-rates/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Invite Codes

Showing 7 of 7 endpoints
GET/invite_codes/admin
Auth requiredinvite-codes.admin.list

List all invite codes (admin)

Returns all invite codes with pagination, status filter, and search. Search matches the code, the creator by email or name, and the redeemer by email or name. Includes creator and redeemer info. Requires features: invite-codes.admin.list

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
statusqueryNoany
createdByUserIdqueryNoany
searchqueryNoany

Responses

200Paginated list of invite codes
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "status": "available",
      "createdByUserId": "00000000-0000-4000-8000-000000000000",
      "createdByName": null,
      "createdByEmail": null,
      "usedByConsumerId": null,
      "usedByName": null,
      "usedByEmail": null,
      "usedAt": null,
      "createdAt": "string",
      "expiresAt": null,
      "revokedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/invite_codes/admin?page=1&pageSize=25&sortField=createdAt&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/invite_codes/admin/generate
Auth requiredinvite-codes.admin.create

Generate invite code (admin)

Generates a new invite code without the 3-code consumer limit. Requires features: invite-codes.admin.create

Request body (application/json)

{
  "expiresAt": null,
  "referenceId": null
}

Responses

200Generated invite code
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "code": "string",
  "createdAt": "string",
  "expiresAt": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
500Failed to generate invite code
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/invite_codes/admin/generate" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"expiresAt\": null,
  \"referenceId\": null
}"
POST/invite_codes/admin/revoke
Auth requiredinvite-codes.admin.revoke

Revoke an invite code (admin)

Revokes an unused invite code. Used codes cannot be revoked. Requires features: invite-codes.admin.revoke

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Code revoked
Content-Type: application/json
{
  "ok": true
}
422Code already used
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/invite_codes/admin/revoke" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
POST/invite_codes/apply
Auth requiredinvite-codes.apply

Apply an invite code to activate account

Applies an invite code to activate the consumer account. Rate limited to 3 requests/min per user. Requires features: invite-codes.apply

Request body (application/json)

{
  "code": "string"
}

Responses

200Account activated
Content-Type: application/json
{
  "activated": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
422Invalid code, already active, or code issue
Content-Type: application/json
{
  "error": "string"
}
429Rate limit exceeded
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/invite_codes/apply" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\"
}"
POST/invite_codes/generate
Auth requiredinvite-codes.generate

Generate a new invite code

Generates a new invite code for the authenticated active consumer. Limited to 3 active codes per consumer. Requires features: invite-codes.generate

Responses

200Generated invite code
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "code": "string",
  "createdAt": "string",
  "expiresAt": null
}
500Failed to generate invite code
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/invite_codes/generate" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/invite_codes/me
Auth requiredinvite-codes.list

List own invite codes

Returns all invite codes created by the authenticated consumer. Requires features: invite-codes.list

Responses

200List of invite codes
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "status": "available",
      "usedAt": null,
      "createdAt": "string",
      "expiresAt": null
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/invite_codes/me" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/invite_codes/verify
Auth requiredinvite-codes.verify

Verify an invite code

Checks whether an invite code is valid without consuming it. Rate limited to 3 requests/min per user. Requires features: invite-codes.verify

Request body (application/json)

{
  "code": "string"
}

Responses

200Code verification result
Content-Type: application/json
{
  "valid": true,
  "scope": "activation",
  "referenceId": null
}
422Invalid, expired, or used code
Content-Type: application/json
{
  "error": "string"
}
429Rate limit exceeded
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/invite_codes/verify" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\"
}"

User Notifications

Showing 8 of 8 endpoints
PUT/user_notifications/{id}/read
Auth required

Mark a notification as read

Marks a single in-app notification belonging to the authenticated user as read. Idempotent — returns ok even if the notification was already read. Notifications belonging to other users return 404.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Notification marked as read
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string",
  "issues": []
}
404Notification not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/user_notifications/00000000-0000-4000-8000-000000000000/read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/user_notifications/mark-all-read
Auth required

Mark all notifications as read

Bulk marks every unread in-app notification belonging to the authenticated user as read. Returns the number of notifications updated.

Responses

200Notifications marked as read
Content-Type: application/json
{
  "ok": true,
  "count": 1
}

Example

curl -X PUT "https://admin.getcovo.com/api/user_notifications/mark-all-read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/user_notifications/notification-preferences
Auth required

Get notification preferences

Returns one preference row per registered notification type. Each entry includes the type, its category, a derived `group` (the prefix before the first dot in the type id), and the `nonOptOut` flag so the client can disable the toggle for forced-on types. Push and email flags default to enabled when no preference is saved.

Responses

200Preferences
Content-Type: application/json
{
  "preferences": [
    {
      "type": "string",
      "category": "string",
      "group": "string",
      "nonOptOut": true,
      "pushEnabled": true,
      "emailEnabled": true
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/user_notifications/notification-preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/user_notifications/notification-preferences
Auth required

Update notification preferences

Batch update preferences. Only types known to the registry are accepted. Types marked as non-opt-out are enforced as enabled server-side regardless of submitted values.

Request body (application/json)

{
  "preferences": [
    {
      "type": "string",
      "pushEnabled": true,
      "emailEnabled": true
    }
  ]
}

Responses

200Updated preferences
Content-Type: application/json
{
  "preferences": [
    {
      "type": "string",
      "category": "string",
      "group": "string",
      "nonOptOut": true,
      "pushEnabled": true,
      "emailEnabled": true
    }
  ]
}
400Invalid input
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/user_notifications/notification-preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"preferences\": [
    {
      \"type\": \"string\",
      \"pushEnabled\": true,
      \"emailEnabled\": true
    }
  ]
}"
GET/user_notifications/notification-types
Auth required

Get notification types

Returns all registered notification types with category, derived `group` (the prefix before the first dot in the type id), opt-out metadata, channels, priority, and localized `title` + `description` strings. Translations are resolved server-side using the request locale (cookie or `Accept-Language`); both fields are `null` for types that do not declare i18n keys (e.g., admin-only types). Used by the mobile app to build the notification settings screen.

Responses

200Notification types
Content-Type: application/json
{
  "types": [
    {
      "type": "string",
      "category": "string",
      "group": "string",
      "nonOptOut": true,
      "silent": true,
      "channels": [
        "push"
      ],
      "priority": "critical",
      "title": null,
      "description": null
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/user_notifications/notification-types" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/user_notifications/push-notification-tokens
Auth required

Register device token

Register or update a device push notification token. Upserts by (tenantId, userId, deviceId). If the same deviceId is registered by another user, any existing active registration is deactivated.

Request body (application/json)

{
  "deviceId": "string",
  "token": "string",
  "platform": "ios",
  "pushPermitted": true
}

Responses

200Token registered
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "deviceId": "string",
  "platform": "ios",
  "pushPermitted": true,
  "isActive": true,
  "locale": null,
  "createdAt": "string"
}
400Invalid input
Content-Type: application/json
{
  "error": "string"
}
409Conflict
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/user_notifications/push-notification-tokens" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"deviceId\": \"string\",
  \"token\": \"string\",
  \"platform\": \"ios\",
  \"pushPermitted\": true
}"
PUT/user_notifications/push-notification-tokens
Auth required

Update device token

Update token value or push permission status for an existing device.

Request body (application/json)

{
  "deviceId": "string"
}

Responses

200Token updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "deviceId": "string",
  "platform": "ios",
  "pushPermitted": true,
  "isActive": true,
  "locale": null,
  "createdAt": "string"
}
400Invalid input
Content-Type: application/json
{
  "error": "string"
}
404Token not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/user_notifications/push-notification-tokens" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"deviceId\": \"string\"
}"
DELETE/user_notifications/push-notification-tokens
Auth required

Deregister device token

Deactivate device token on logout.

Request body (application/json)

{
  "deviceId": "string"
}

Responses

200Token deactivated
Content-Type: application/json
{
  "ok": true
}
400Invalid input
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/user_notifications/push-notification-tokens" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"deviceId\": \"string\"
}"

Families

Showing 12 of 12 endpoints
POST/families
Auth requiredfamilies.create

Create a family

Creates a new family with the authenticated user as admin. Returns 409 if the user already belongs to a family. Requires features: families.create

Responses

201Family created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "ownerUserId": "00000000-0000-4000-8000-000000000000",
  "role": "admin"
}
409User already belongs to a family
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/families" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/families/{id}
Auth requiredfamilies.delete

Delete a family

Soft-deletes the family and all active memberships. Only the family admin (owner) may delete. Returns the list of user ids removed so billing subscribers can revert per-user configuration. Requires features: families.delete

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Family deleted
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "removedUserIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/families/{id}/invitations
Auth requiredfamilies.invitations.view

List family invitations

Returns all invitation codes for the family. Only the family admin (owner) can view the list. Requires features: families.invitations.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Invitation list
Content-Type: application/json
{
  "invitations": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "invitedName": null,
      "createdByUserId": "00000000-0000-4000-8000-000000000000",
      "usedByConsumerId": null,
      "usedAt": null,
      "expiresAt": null,
      "revokedAt": null,
      "createdAt": "string"
    }
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000/invitations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/families/{id}/invitations
Auth requiredfamilies.invitations.generate

Generate a family invitation code

Generates a new family invitation code. Only the family admin (owner) can generate invitations. Codes expire after 7 days. Limited to 10 active invitations per family and rate limited to 3 requests per 60 seconds per user. Pass role "child" to create a child-role invitation. Requires features: families.invitations.generate

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "role": "member"
}

Responses

201Invitation generated
Content-Type: application/json
{
  "code": "string",
  "expiresAt": "string"
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}
409Active invitation limit reached
Content-Type: application/json
{
  "error": "string"
}
429Rate limit exceeded
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000/invitations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"role\": \"member\"
}"
DELETE/families/{id}/invitations/{code}
Auth requiredfamilies.invitations.revoke

Revoke a family invitation code

Revokes a family invitation code. Only the family admin (owner) can revoke invitations. Cannot revoke an already-used or already-revoked invitation. Requires features: families.invitations.revoke

Parameters

NameInRequiredSchemaDescription
idpathYesany
codepathYesany

Responses

200Invitation revoked
Content-Type: application/json
{
  "code": "string",
  "revokedAt": "string"
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family or invitation not found
Content-Type: application/json
{
  "error": "string"
}
409Invitation already revoked or already used
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000/invitations/string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/families/{id}/leave
Auth requiredfamilies.leave

Leave a family

Removes the authenticated caller from the family (soft-delete) and emits families.family-member.removed. The family admin (owner) cannot leave — they must delete the family instead. Requires features: families.leave

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Left the family
Content-Type: application/json
{
  "familyId": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000"
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family or membership not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000/leave" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/families/{id}/members
Auth requiredfamilies.members.view

List family members

Returns members of the family, each with their spending cap and monthlySpentEuroCents (eSIM spend for the current calendar month in UTC; a live sum with no stored reset). Only members of the family can view the list. Requires features: families.members.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Member list
Content-Type: application/json
{
  "members": [
    {
      "userId": "00000000-0000-4000-8000-000000000000",
      "role": "admin",
      "invitedName": null,
      "spendingCapEuroCents": null,
      "monthlySpentEuroCents": 1,
      "joinedAt": "string"
    }
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000/members" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/families/{id}/members/{userId}
Auth requiredfamilies.members.update

Update a family member

Admin-only (family owner). Updates a member's display name, role, and/or spending cap in a single call. Only provided fields are changed. Role is restricted to "member" or "child"; the family admin's own role and cap cannot be changed. Emits families.family-member.role-changed and/or families.family-member.cap-changed when those fields change. Requires features: families.members.update

Parameters

NameInRequiredSchemaDescription
idpathYesany
userIdpathYesany

Request body (application/json)

{
  "spendingCapEuroCents": null
}

Responses

200Member updated
Content-Type: application/json
{
  "familyId": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000",
  "invitedName": null,
  "role": "admin",
  "spendingCapEuroCents": null
}
400Invalid params, invalid/empty body, or cannot set role/cap for the family admin
Content-Type: application/json
{
  "error": "string"
}
404Family or member not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000/members/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"spendingCapEuroCents\": null
}"
DELETE/families/{id}/members/{userId}
Auth requiredfamilies.members.remove

Remove a family member

Admin-only. Removes a member from the family (soft-delete) and emits families.family-member.removed. The admin (owner) cannot be removed — delete the family instead. Requires features: families.members.remove

Parameters

NameInRequiredSchemaDescription
idpathYesany
userIdpathYesany

Responses

200Member removed
Content-Type: application/json
{
  "familyId": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000"
}
400Invalid params or cannot remove the owner
Content-Type: application/json
{
  "error": "string"
}
404Family or member not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/families/00000000-0000-4000-8000-000000000000/members/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/families/join
Auth requiredfamilies.join

Join a family

Joins the authenticated user to a family using a valid invitation code. Returns 409 if the code is already used, revoked, or the user is already in a family. Requires features: families.join

Request body (application/json)

{
  "code": "string"
}

Responses

201Joined the family
Content-Type: application/json
{
  "familyId": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000",
  "role": "admin"
}
400Missing or invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Invitation or family not found
Content-Type: application/json
{
  "error": "string"
}
409Invitation already used, revoked, or user already in family
Content-Type: application/json
{
  "error": "string"
}
422Family is full or consumer profile not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/families/join" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\"
}"
GET/families/lookup
Auth requiredfamilies.view

Look up a family by invitation code

Returns family details for a valid invitation code. Returns 409 if the code is expired, revoked, or already used. Rate limited to 10 requests/min per user. Requires features: families.view

Parameters

NameInRequiredSchemaDescription
codequeryYesany

Responses

200Family preview
Content-Type: application/json
{
  "familyId": "00000000-0000-4000-8000-000000000000",
  "ownerUserId": "00000000-0000-4000-8000-000000000000",
  "memberCount": 1,
  "code": "string",
  "expiresAt": null
}
400Missing or invalid code param
Content-Type: application/json
{
  "error": "string"
}
404Invitation or family not found
Content-Type: application/json
{
  "error": "string"
}
409Invitation expired, revoked, or already used
Content-Type: application/json
{
  "error": "string"
}
429Rate limit exceeded
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/families/lookup?code=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/families/me
Auth requiredfamilies.view

Get the authenticated user's family

Returns the family the user belongs to, or null when the user has no family yet. Requires features: families.view

Responses

200Family or null
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/families/me" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Gifts

Showing 6 of 6 endpoints
POST/gifts/admin/workers/expire-gifts
Auth requiredgifts.admin.run_expire_sweep

Run expire-gifts sweep worker inline

Executes the gift expiry sweep worker synchronously in the request handler. Used for integration tests and operational diagnostics; the scheduler normally invokes this worker on a 15-minute cron. Request body is ignored. Requires features: gifts.admin.run_expire_sweep

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/gifts/admin/workers/expire-gifts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gifts/me/gifts
Auth requiredgifts.view

List the caller's sent gifts

Returns the caller's gifts, newest first. Scoped to `sender_user_id = auth.sub` and the caller's organization. Requires features: gifts.view

Parameters

NameInRequiredSchemaDescription
statusqueryNoany
limitqueryNoany
offsetqueryNoany

Responses

200Caller's gifts
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "originalCurrency": "string",
      "originalAmountMinorUnits": 1,
      "amountEuroCents": 1,
      "status": "string",
      "code": "string",
      "claimedByUserId": null,
      "claimedAt": null,
      "cancelledAt": null,
      "expiredAt": null,
      "expiresAt": "string",
      "createdAt": "string"
    }
  ],
  "total": 1
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/gifts/me/gifts?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gifts/me/gifts
Auth requiredgifts.send

Send a gift

Creates a pending gift by debiting the caller's standard wallet for the EUR-equivalent of the requested amount (FIFO over credit batches in the caller's `displayCurrency`) and issuing a 7-day invitation code with `scope: "gift"`. `originalCurrency` MUST equal the caller's `displayCurrency` (else `409 currency_mismatch`). `originalAmountMinorUnits` MUST fall in `giftBounds(originalCurrency)` (else `422 amount_out_of_range`). The response's `amountEuroCents` is the actual EUR debited, which may differ slightly from a today's-rate conversion because the walk honours each top-up's realized rate. Requires features: gifts.send

Request body (application/json)

{
  "originalCurrency": "string",
  "originalAmountMinorUnits": 1
}

Responses

201Gift created
Content-Type: application/json
{
  "giftId": "00000000-0000-4000-8000-000000000000",
  "code": "string",
  "expiresAt": "string",
  "originalCurrency": "string",
  "originalAmountMinorUnits": 1,
  "amountEuroCents": 1
}
400Validation error
Content-Type: application/json
{
  "error": "string"
}
409gift_limit_reached (≥10 pending) or currency_mismatch (originalCurrency != displayCurrency)
Content-Type: application/json
{
  "error": "string"
}
422insufficient_balance or amount_out_of_range
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/gifts/me/gifts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"originalCurrency\": \"string\",
  \"originalAmountMinorUnits\": 1
}"
DELETE/gifts/me/gifts/{id}
Auth requiredgifts.cancel

Cancel a pending gift

Refunds the gift's `amountEuroCents` to the sender's standard wallet as a `gift_refund` credit batch that inherits the gift's original currency and amount, then revokes the invite code. Only `pending` gifts and only the sender can cancel. Requires features: gifts.cancel

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Gift cancelled and refund issued
Content-Type: application/json
{
  "giftId": "00000000-0000-4000-8000-000000000000",
  "status": "string",
  "refundTransactionId": "00000000-0000-4000-8000-000000000000"
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Gift not found
Content-Type: application/json
{
  "error": "string"
}
409Gift not in pending state
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/gifts/me/gifts/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gifts/me/gifts/bounds
Auth requiredgifts.view

Gift amount bounds in the caller's display currency

Returns the gift amount slider bounds for the caller, derived from the €1–€200 product guardrail converted to the caller's `displayCurrency` at today's rate and rounded up to a friendly per-currency granularity. All values are in minor units of `currency` (the caller's `displayCurrency`, defaulting to EUR when no consumer profile exists). The frontend slider SHOULD step by `granularityMinorUnits` between `minMinorUnits` and `maxMinorUnits`. Backed by the same `giftBounds` helper that validates `POST /api/me/gifts`, so the slider and server validation cannot drift. Bounds are recomputed per request at today's rate, so a rate move silently nudges them. Requires features: gifts.view

Responses

200Gift bounds in the caller's display currency
Content-Type: application/json
{
  "currency": "string",
  "granularityMinorUnits": 1,
  "minMinorUnits": 1,
  "maxMinorUnits": 1
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/gifts/me/gifts/bounds" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gifts/me/gifts/claim
Auth requiredgifts.claim

Claim a gift

Claims a pending gift the authenticated user received. Credits the gift amount to the caller's standard wallet (which is created on first access), marks the invitation code used, and activates the caller's consumer profile if it is not already active. Allowed for new and already-active accounts; the sender may not claim their own gift. Rate limited per user and per source IP. Requires features: gifts.claim

Request body (application/json)

{
  "code": "string"
}

Responses

200Gift claimed and recipient wallet credited
Content-Type: application/json
{
  "giftId": "00000000-0000-4000-8000-000000000000",
  "originalCurrency": "string",
  "originalAmountMinorUnits": 1,
  "amountEuroCents": 1,
  "status": "string"
}
400Missing or invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Invitation code not found or not a gift
Content-Type: application/json
{
  "error": "string"
}
409Invitation already used, gift not pending, or sender attempting self-claim
Content-Type: application/json
{
  "error": "string"
}
410Invitation or gift has expired or been revoked
Content-Type: application/json
{
  "error": "string"
}
422Consumer profile not found for the authenticated user
Content-Type: application/json
{
  "error": "string"
}
429Rate limit exceeded
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/gifts/me/gifts/claim" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\"
}"

Savings

Showing 4 of 4 endpoints
GET/savings/admin/wallets/{walletId}
Auth requiredsavings.admin.view

Get a wallet's lifetime savings

Admin variant of GET /api/savings/me. Returns the EUR locked into the lifetime savings counter for the given wallet, its display-currency and data-equivalent projections, and the EUR still pending in un-matured top-ups with its display-currency projection. Scoped to the caller's tenant/organization. Requires features: savings.admin.view

Parameters

NameInRequiredSchemaDescription
walletIdpathYesany

Responses

200Lifetime savings summary
Content-Type: application/json
{
  "lifetime": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "lifetimeData": {
    "bytes": 1
  },
  "pending": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "maturesNextAt": null
}
400Invalid wallet id
Content-Type: application/json
{
  "error": "string"
}
404Wallet not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/savings/admin/wallets/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/savings/admin/workers/mature-top-up-batches
Auth requiredsavings.admin.run_maturation

Run the top-up batch maturation worker inline

Executes the maturation worker synchronously in the request handler. Used for integration tests and operational diagnostics; the scheduler normally invokes this worker on a one-minute cron. Request body is ignored. Requires features: savings.admin.run_maturation

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/savings/admin/workers/mature-top-up-batches" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/savings/admin/workers/wallet-savings-retention
Auth requiredsavings.admin.run_retention

Run wallet-savings-retention worker inline

Executes the wallet savings retention purge worker synchronously. Hard-deletes wallet_savings rows for users past their account_deletion_waivers.purge_after date. Used for integration tests and operational diagnostics. Requires features: savings.admin.run_retention

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/savings/admin/workers/wallet-savings-retention" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/savings/me
Auth requiredsavings.view

Get the caller's lifetime savings

Returns the EUR locked into the lifetime savings counter by matured top-up batches, its display-currency and data-equivalent projections, and the EUR still pending in un-matured top-ups with its display-currency projection. Scoped to the caller's standard wallet. Requires features: savings.view

Responses

200Lifetime savings summary
Content-Type: application/json
{
  "lifetime": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "lifetimeData": {
    "bytes": 1
  },
  "pending": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "maturesNextAt": null
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/savings/me" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

DNS Filtering

Showing 7 of 7 endpoints
POST/dns_filtering/admin/workers/charge-network-turbo
Auth requireddns_filtering.network_turbo.admin_update

Run charge-network-turbo worker inline

Executes the hourly Network Turbo renewal worker synchronously in the request handler. Used for integration tests and operational diagnostics; the scheduler normally invokes this worker on an hourly cron. Request body is ignored. Requires features: dns_filtering.network_turbo.admin_update

Responses

200Worker completed
Content-Type: application/json
{
  "ok": true
}
500Worker failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/dns_filtering/admin/workers/charge-network-turbo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/dns_filtering/families/{id}/child-safety
Auth requireddns_filtering.safety.view

Get the family's children safety settings

Any family member may read. Returns the two DNS-related toggles plus a derived protectionStatus. When the family has no child members, both toggles are false and protectionStatus is "none". Requires features: dns_filtering.safety.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Family children safety settings
Content-Type: application/json
{
  "contentFilterEnabled": true,
  "safeWebEnabled": true,
  "protectionStatus": "fully"
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/families/00000000-0000-4000-8000-000000000000/child-safety" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dns_filtering/families/{id}/child-safety
Auth requireddns_filtering.safety.update

Update the family's children safety settings

Admin-only. Updates contentFilterEnabled and/or safeWebEnabled for all child members. Emits dns_filtering.safety.updated. Requires features: dns_filtering.safety.update

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{}

Responses

200Updated children safety settings
Content-Type: application/json
{
  "contentFilterEnabled": true,
  "safeWebEnabled": true,
  "protectionStatus": "fully"
}
400Invalid params or body
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}
409Family has no child members to apply settings to
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/dns_filtering/families/00000000-0000-4000-8000-000000000000/child-safety" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
PUT/dns_filtering/families/{id}/members/{memberId}/network-turbo
Auth requireddns_filtering.network_turbo.admin_update

Enable or disable Network Turbo on behalf of a family member

Family admin only. Enabling charges the admin's standard wallet upfront for the current cycle and writes a `fundedBy='family-admin'` entitlement for the member. If the member is currently self-paying (state='active' personal row), that row is frozen with `bankedUntil` capturing the unused prepaid time and `pausedAt` set to now — preserving the member's banked prepaid days for handoff when the admin record ends. Disabling defers: it flips auto-renewal off but keeps the admin-funded record active through its paid cycle (no refund); the renewal worker performs the handoff to the frozen personal sibling when the cycle elapses. Requires features: dns_filtering.network_turbo.admin_update

Parameters

NameInRequiredSchemaDescription
idpathYesany
memberIdpathYesany

Request body (application/json)

{
  "enabled": true
}

Responses

200Updated Network Turbo status for the member
Content-Type: application/json
{
  "enabled": true,
  "fundedBy": null,
  "paidUntil": null,
  "autoRenewalEnabled": true,
  "self": {
    "state": "string",
    "paidUntil": null,
    "bankedUntil": null,
    "pausedAt": null,
    "autoRenewalEnabled": true
  },
  "familyAdmin": {
    "state": "string",
    "paidUntil": null,
    "bankedUntil": null,
    "pausedAt": null,
    "autoRenewalEnabled": true
  }
}
400Invalid params/body, or admin tried to fund themselves (cannot_admin_fund_self)
Content-Type: application/json
{
  "error": "string"
}
402Insufficient admin wallet balance
Content-Type: application/json
{
  "error": "string"
}
404Family or member not found
Content-Type: application/json
{
  "error": "string"
}
409A different family admin currently funds Network Turbo for this member (funded_by_different_admin)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/dns_filtering/families/00000000-0000-4000-8000-000000000000/members/00000000-0000-4000-8000-000000000000/network-turbo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"enabled\": true
}"
GET/dns_filtering/users/me/dns-config
Auth required

Get the resolved DNS configuration for the current user

Returns the DNS provider, DoH URL, fallback IPs, and the reasons filtering is active. The mobile app calls this on launch and when it receives a dns_config_changed silent push, then applies the returned configuration to the OS DNS settings. Children's Safety inputs only apply when the caller's family role is 'child'; otherwise they are ignored.

Responses

200Resolved DNS configuration
Content-Type: application/json
{
  "dnsMode": "default",
  "dohUrl": "https://example.com/resource",
  "dnsIps": [
    "string"
  ],
  "provider": "cloudflare-family",
  "reason": [
    "string"
  ],
  "enforcedBy": "self",
  "lastUpdatedAt": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/users/me/dns-config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/dns_filtering/users/me/network-turbo
Auth requireddns_filtering.network_turbo.view

Get the current user's Network Turbo status

Returns the caller's Network Turbo status as a per-source breakdown plus effective top-level fields. The `self` object reflects the caller's personally-funded record; the `familyAdmin` object reflects any family-admin-funded record covering the caller. Each source has `state` ('active', 'frozen', or 'disabled'), `paidUntil`, `bankedUntil`, `pausedAt`, and `autoRenewalEnabled`. `state='frozen'` means the user has banked prepaid time on this source while the sibling source is currently paying. Top-level `enabled`, `fundedBy`, `paidUntil`, and `autoRenewalEnabled` come from the currently paying row (the `active` row, or the `frozen` row as a transient fallback). Users with no Network Turbo rows return defaults with both sources disabled. Requires features: dns_filtering.network_turbo.view

Responses

200Network Turbo status
Content-Type: application/json
{
  "enabled": true,
  "fundedBy": null,
  "paidUntil": null,
  "autoRenewalEnabled": true,
  "self": {
    "state": "string",
    "paidUntil": null,
    "bankedUntil": null,
    "pausedAt": null,
    "autoRenewalEnabled": true
  },
  "familyAdmin": {
    "state": "string",
    "paidUntil": null,
    "bankedUntil": null,
    "pausedAt": null,
    "autoRenewalEnabled": true
  }
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/users/me/network-turbo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dns_filtering/users/me/network-turbo
Auth requireddns_filtering.network_turbo.update

Enable or disable Network Turbo for the current user

Self-activation for Network Turbo. Enabling from a disabled state charges the user's wallet upfront for the current calendar month, stamps fundedBy='self', and turns auto-renewal on. Strictly prepaid: returns 402 if the wallet balance is below the configured price. Disabling is deferred: it flips auto-renewal off but keeps Turbo on until the current paid period ends — no wallet refund. Re-enabling within an already-paid cycle simply flips auto-renewal back on without charging. Enabling is rejected with 409 conflict_admin_funded while a family admin is currently paying for Turbo on this user. Requires features: dns_filtering.network_turbo.update

Request body (application/json)

{
  "enabled": true
}

Responses

200Updated Network Turbo status
Content-Type: application/json
{
  "enabled": true,
  "fundedBy": null,
  "paidUntil": null,
  "autoRenewalEnabled": true,
  "self": {
    "state": "string",
    "paidUntil": null,
    "bankedUntil": null,
    "pausedAt": null,
    "autoRenewalEnabled": true
  },
  "familyAdmin": {
    "state": "string",
    "paidUntil": null,
    "bankedUntil": null,
    "pausedAt": null,
    "autoRenewalEnabled": true
  }
}
400Invalid body
Content-Type: application/json
{
  "error": "string"
}
402Insufficient wallet balance
Content-Type: application/json
{
  "error": "string"
}
409Personal Turbo cannot be enabled while a family admin is currently paying for it
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/dns_filtering/users/me/network-turbo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"enabled\": true
}"

Data Exports

Showing 4 of 4 endpoints
GET/data_exports/admin/config
Auth requireddata_exports.config.view

Get the effective data export configuration

Returns the effective per-tenant checklist configuration: each item key mapped to its enabled flag (checklist defaults overlaid by stored deviations), plus the list of gated item keys that are clamped OFF pending legal sign-off. Requires features: data_exports.config.view

Responses

200Effective configuration
Content-Type: application/json
{
  "enabledItems": {
    "key": true
  },
  "gatedItems": [
    "string"
  ],
  "items": [
    {
      "key": "string",
      "domain": "string",
      "titleKey": "string",
      "gated": true,
      "enabled": true
    }
  ]
}
500Failed to load configuration
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/data_exports/admin/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/data_exports/admin/config
Auth requireddata_exports.config.update

Update the data export configuration (admin)

Persists the per-tenant checklist deviations (sparse enabledItems map; keys must belong to the registered taxonomy). Returns the freshly resolved effective config. Gated items remain clamped OFF regardless of what is posted. Requires features: data_exports.config.update

Request body (application/json)

{
  "enabledItems": {
    "key": true
  }
}

Responses

200Updated effective configuration
Content-Type: application/json
{
  "enabledItems": {
    "key": true
  },
  "gatedItems": [
    "string"
  ]
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
500Failed to update configuration
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/data_exports/admin/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"enabledItems\": {
    \"key\": true
  }
}"
GET/data_exports/exports/{id}/download

Download a delivered data export bundle

Serves the zip bundle (PDF + CSV/JSON) for a delivered export. S3-backed partitions return a 302 redirect to a short-lived presigned URL (the bundle bytes never pass through the backend); on-disk dev/test partitions return the body inline. Access is gated solely by a signed, unexpired download token (`t`) whose request id matches the path id — no session is required. Returns 403 for an invalid/expired/mismatched token and 404 when the export is not delivered or no longer available.

Parameters

NameInRequiredSchemaDescription
idpathYesany
tqueryYesany

Responses

200Zip bundle (returned inline for on-disk partitions)
Content-Type: application/zip
string
302Redirect to a short-lived presigned download URL
Content-Type: application/json
"string"
400Invalid id or token
Content-Type: application/json
{
  "error": "string"
}
403Invalid or expired link
Content-Type: application/json
{
  "error": "string"
}
404Export not found or not delivered
Content-Type: application/json
{
  "error": "string"
}
500Failed to load export
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/data_exports/exports/00000000-0000-4000-8000-000000000000/download?t=string" \
  -H "Accept: application/json"
POST/data_exports/me/exports
Auth requireddata_exports.request.create

Request a personal data export

Lets the authenticated user trigger their own GDPR data export (in-app self-service channel). Requires a recent re-authentication via email OTP or social ID token. Creates a data-export request in the `requested` state and enqueues automated assembly; the request parks at `assembled` and is not delivered until an admin reviews and sends it. Requires features: data_exports.request.create

Request body (application/json)

{
  "reauth": {
    "method": "otp",
    "code": "string"
  }
}

Responses

202Export request accepted and queued for assembly
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "requested"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to request data export
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/data_exports/me/exports" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"reauth\": {
    \"method\": \"otp\",
    \"code\": \"string\"
  }
}"

Waitlist

Showing 4 of 4 endpoints
GET/waitlist/admin
Auth requiredwaitlist.view

List waitlist entries (admin)

Returns all waitlist entries with pagination, status filter, and search by email, first name or last name. Requires features: waitlist.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
statusqueryNoany
searchqueryNoanyFilter entries whose email contains this substring (case-insensitive)

Responses

200Paginated list of waitlist entries
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "firstName": "string",
      "lastName": "string",
      "email": "string",
      "status": "pending",
      "referenceId": null,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/waitlist/admin?page=1&pageSize=25&sortField=createdAt&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/waitlist/admin/{id}
Auth requiredwaitlist.manage

Soft-delete a waitlist entry (admin)

Marks a waitlist entry as deleted so it can be restored later. Does not affect any invite code already issued. Requires features: waitlist.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Entry soft-deleted
Content-Type: application/json
{
  "ok": true
}
404Entry not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/waitlist/admin/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/waitlist/admin/grant
Auth requiredwaitlist.manage

Grant invite to waitlist entries (admin)

Generates an activation code for each pending entry and marks them as invited. Already-invited entries are skipped. Bulk-capable (up to 100 IDs). Requires features: waitlist.manage

Request body (application/json)

{
  "ids": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

200Grant result
Content-Type: application/json
{
  "grantedIds": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "skippedIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404One or more entries not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/waitlist/admin/grant" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"ids\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"
POST/waitlist/signup

Sign up for the waitlist

Adds an email to the waitlist. Idempotent — submitting the same email again returns the same response. Rate limited to 5 requests per 10 minutes per IP.

Request body (application/json)

{
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com"
}

Responses

200Added to waitlist (or already on it)
Content-Type: application/json
{
  "status": "pending"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
429Rate limit exceeded
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/waitlist/signup" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"firstName\": \"string\",
  \"lastName\": \"string\",
  \"email\": \"user@example.com\"
}"

Auth

Showing 1 of 1 endpoints
GET/auth/users/consents
Auth requiredauth.users.edit

List user consents

Returns all consent records for a given user, with integrity verification status. Requires features: auth.users.edit

Parameters

NameInRequiredSchemaDescription
userIdqueryYesany

Responses

200Consent list returned
Content-Type: application/json
"string"

Example

curl -X GET "https://admin.getcovo.com/api/auth/users/consents?userId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Authentication

Showing 3 of 3 endpoints
POST/better_auth/otp/request

Request a 6-digit email OTP for sign-in or sign-up

Sends a one-time code to the provided email address. Always returns 200 with { ok: true } regardless of whether the email maps to an existing user, to prevent account enumeration. A per-email cooldown (60s, sha256-keyed) returns 429 { error: "otp_cooldown", retryAfterSeconds } with a Retry-After header — the cooldown is keyed independently of user existence, so it does not leak enumeration signal. Plugin errors are logged but never surfaced.

Request body (application/json)

{
  "email": "user@example.com"
}

Responses

200Request accepted (no signal about account existence)
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
429Per-email cooldown active; retry after the indicated number of seconds
Content-Type: application/json
{
  "error": "string",
  "retryAfterSeconds": 1
}

Example

curl -X POST "https://admin.getcovo.com/api/better_auth/otp/request" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\"
}"
POST/better_auth/otp/verify

Verify a 6-digit email OTP and issue a platform session

Verifies the OTP via BetterAuth (atomic verification with attempt counter and expiry). On success, creates the user if missing, then issues a platform JWT and refresh token. Returns generic error messages for invalid/expired codes to avoid leaking which one applied.

Request body (application/json)

{
  "email": "user@example.com",
  "otp": "string"
}

Responses

200OTP verified, session issued
Content-Type: application/json
{
  "token": "string",
  "refreshToken": "string",
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "userId": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "firstName": null,
    "lastName": null,
    "phone": null,
    "languageCode": null,
    "displayCurrency": null,
    "homeCountryCode": null,
    "travelProfile": null,
    "birthDate": null,
    "address": null,
    "billing": null,
    "active": true,
    "createdAt": "string"
  },
  "isNewUser": true
}
400Invalid payload, invalid or expired code, or unsupported currency
Content-Type: application/json
{
  "error": "string"
}
429Too many verification attempts
Content-Type: application/json
{
  "error": "string"
}
500OTP login failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/better_auth/otp/verify" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"otp\": \"string\"
}"
POST/better_auth/social

Sign in or sign up with a social provider

Verifies the provider ID token via BetterAuth, creates or finds the user, and returns a platform JWT.

Request body (application/json)

{
  "provider": "google",
  "token": "string"
}

Responses

200SSO authentication successful
Content-Type: application/json
{
  "token": "string",
  "refreshToken": "string",
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "userId": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "firstName": null,
    "lastName": null,
    "phone": null,
    "languageCode": null,
    "displayCurrency": null,
    "homeCountryCode": null,
    "travelProfile": null,
    "birthDate": null,
    "address": null,
    "billing": null,
    "active": true,
    "createdAt": "string"
  },
  "isNewUser": true
}
400Invalid payload or unsupported provider
Content-Type: application/json
{
  "error": "string"
}
401Invalid or expired token
Content-Type: application/json
{
  "error": "string"
}
500SSO processing failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/better_auth/social" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"provider\": \"google\",
  \"token\": \"string\"
}"

Configs

Showing 6 of 6 endpoints
GET/configs/cache
Auth requiredconfigs.cache.view

Get cache statistics

Returns detailed cache statistics including total entries and breakdown by cache segments. Requires cache service to be available. Requires features: configs.cache.view

Responses

200Cache statistics
Content-Type: application/json
{
  "total": 1,
  "segments": {
    "key": 1
  }
}
500Failed to resolve cache stats
Content-Type: application/json
{
  "error": "string"
}
503Cache service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/cache
Auth requiredconfigs.cache.manage

Purge cache

Purges cache entries. Supports two actions: purgeAll (clears entire cache) or purgeSegment (clears specific segment). Returns updated cache statistics after purge. Requires features: configs.cache.manage

Request body (application/json)

{
  "action": "purgeAll"
}

Responses

200Cache segment cleared successfully
Content-Type: application/json
{
  "action": "purgeSegment",
  "segment": "string",
  "deleted": 1,
  "stats": {
    "total": 1,
    "segments": {
      "key": 1
    }
  }
}
400Invalid request - missing segment identifier for purgeSegment action
Content-Type: application/json
{
  "error": "string"
}
500Failed to purge cache
Content-Type: application/json
{
  "error": "string"
}
503Cache service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"action\": \"purgeAll\"
}"
GET/configs/system-status
Auth requiredconfigs.system_status.view

Get system health status

Returns comprehensive system health information including environment details, version, resource usage, and service connectivity status. Requires features: configs.system_status.view

Responses

200System status snapshot
Content-Type: application/json
{
  "generatedAt": "string",
  "runtimeMode": "development",
  "categories": [
    {
      "key": "profiling",
      "labelKey": "string",
      "descriptionKey": null,
      "items": [
        {
          "key": "string",
          "category": "profiling",
          "kind": "boolean",
          "labelKey": "string",
          "descriptionKey": "string",
          "docUrl": null,
          "defaultValue": null,
          "state": "enabled",
          "value": null,
          "normalizedValue": null
        }
      ]
    }
  ]
}
500Failed to load system status
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/system-status
Auth requiredconfigs.manage

Clear system cache

Purges the entire cache for the current tenant. Useful for troubleshooting or forcing fresh data loading. Requires features: configs.manage

Responses

200Cache cleared successfully
Content-Type: application/json
{
  "cleared": true
}
500Failed to purge cache
Content-Type: application/json
{
  "error": "string"
}
503Cache service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/configs/upgrade-actions
Auth requiredconfigs.manage

List pending upgrade actions

Returns a list of pending upgrade actions for the current version. These are one-time setup tasks that need to be executed after upgrading to a new version. Requires organization and tenant context. Requires features: configs.manage

Responses

200List of pending upgrade actions
Content-Type: application/json
{
  "version": "string",
  "actions": [
    {
      "id": "string",
      "version": "string",
      "message": "string",
      "ctaLabel": "string",
      "successMessage": "string",
      "loadingLabel": "string"
    }
  ]
}
400Missing organization or tenant context
Content-Type: application/json
{
  "error": "string"
}
500Failed to load upgrade actions
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/upgrade-actions
Auth requiredconfigs.manage

Execute upgrade action

Executes a specific upgrade action by ID. Typically used for one-time setup tasks like seeding example data after version upgrade. Returns execution status and localized success message. Requires features: configs.manage

Request body (application/json)

{
  "actionId": "string"
}

Responses

200Upgrade action executed successfully
Content-Type: application/json
{
  "status": "string",
  "message": "string",
  "version": "string"
}
400Invalid request body or missing context
Content-Type: application/json
{
  "error": "string"
}
500Failed to execute upgrade action
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"actionId\": \"string\"
}"

Consumers

Showing 16 of 16 endpoints
GET/consumers/admin
Auth requiredconsumers.admin.list

List consumers

Returns consumers with pagination and search. The search query matches partial email (via the search token index), first name, and last name. Pass id query param to get a single consumer. Requires features: consumers.admin.list

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
searchqueryNoany
idqueryNoany
userIdqueryNoany

Responses

200Consumer list
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "email": "user@example.com",
      "firstName": null,
      "lastName": null,
      "phone": null,
      "languageCode": null,
      "displayCurrency": null,
      "homeCountryCode": null,
      "travelProfile": null,
      "birthDate": null,
      "address": null,
      "billing": null,
      "active": true,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/admin?page=1&pageSize=50&sortField=createdAt&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/consumers/admin
Auth requiredconsumers.admin.create

Create consumer

Creates a new user and consumer profile. Requires features: consumers.admin.create

Request body (application/json)

{
  "email": "user@example.com",
  "password": "string",
  "firstName": null,
  "lastName": null,
  "phone": null,
  "languageCode": null,
  "displayCurrency": null,
  "homeCountryCode": null,
  "travelProfile": null,
  "birthDate": null,
  "address": null,
  "billing": null
}

Responses

201Consumer created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
409Email already exists
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/consumers/admin" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"password\": \"string\",
  \"firstName\": null,
  \"lastName\": null,
  \"phone\": null,
  \"languageCode\": null,
  \"displayCurrency\": null,
  \"homeCountryCode\": null,
  \"travelProfile\": null,
  \"birthDate\": null,
  \"address\": null,
  \"billing\": null
}"
PUT/consumers/admin
Auth requiredconsumers.admin.update

Update consumer

Updates a consumer profile by id. Requires features: consumers.admin.update

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "firstName": null,
  "lastName": null,
  "phone": null,
  "languageCode": null,
  "displayCurrency": null,
  "homeCountryCode": null,
  "travelProfile": null,
  "birthDate": null,
  "address": null,
  "billing": null
}

Responses

200Consumer updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Consumer not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/consumers/admin" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"firstName\": null,
  \"lastName\": null,
  \"phone\": null,
  \"languageCode\": null,
  \"displayCurrency\": null,
  \"homeCountryCode\": null,
  \"travelProfile\": null,
  \"birthDate\": null,
  \"address\": null,
  \"billing\": null
}"
DELETE/consumers/admin
Auth requiredconsumers.admin.delete

Delete consumer

Soft-deletes a consumer profile by id. Requires features: consumers.admin.delete

Parameters

NameInRequiredSchemaDescription
idqueryYesanyConsumer profile identifier

Responses

200Consumer deleted
Content-Type: application/json
{
  "ok": true
}
400Missing id
Content-Type: application/json
{
  "error": "string"
}
404Consumer not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/consumers/admin?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/consumers/admin/{id}/auto-refill
Auth requiredconsumers.admin.list

Get consumer auto-refill configuration and recent charge

Returns auto-refill configuration, monthly spent counter, and the most recent auto-refill payment for the given consumer profile. Requires features: consumers.admin.list

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Auto-refill admin detail
Content-Type: application/json
{
  "enabled": true,
  "amountEuroCents": null,
  "thresholdEuroCents": null,
  "monthlyCapEuroCents": null,
  "monthlySpentEuroCents": 1,
  "pausedAt": null,
  "pausedReason": null,
  "lastCharge": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Consumer not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load auto-refill data
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/admin/00000000-0000-4000-8000-000000000000/auto-refill" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/consumers/admin/{id}/spending-cap
Auth requiredconsumers.admin.view

Get personal spending cap status for a consumer (admin)

Returns the personal cap, current monthly eSIM spend, and family membership flags (isFamilyMember/isFamilyAdmin) for the consumer. Requires features: consumers.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Personal spending cap status
Content-Type: application/json
{
  "userId": "00000000-0000-4000-8000-000000000000",
  "personalSpendingCapEuroCents": null,
  "monthlySpentEuroCents": 1,
  "isFamilyMember": true,
  "isFamilyAdmin": true
}
404Consumer not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/admin/00000000-0000-4000-8000-000000000000/spending-cap" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/consumers/admin/{id}/spending-cap
Auth requiredconsumers.admin.update

Set or clear personal monthly spending cap for a consumer (admin)

Backoffice admin sets or clears the monthly eSIM spending cap (in EUR cents) for the given consumer profile. Pass null to clear. Rejected if the consumer is a non-admin family member. Requires features: consumers.admin.update

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "capEuroCents": null
}

Responses

200Personal spending cap updated
Content-Type: application/json
{
  "userId": "00000000-0000-4000-8000-000000000000",
  "personalSpendingCapEuroCents": null
}
400Invalid body, params, or consumer is a non-admin family member
Content-Type: application/json
{
  "error": "string"
}
404Consumer not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/consumers/admin/00000000-0000-4000-8000-000000000000/spending-cap" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"capEuroCents\": null
}"
GET/consumers/admin/currency-usage
Auth requiredcurrencies.manage

Count consumers using a given display currency (admin)

Returns the number of active consumer profiles whose display currency matches the given ISO 4217 code, scoped to the caller tenant/organization. Used to warn admins before deactivating or deleting a currency, since affected consumers are moved to EUR. Requires features: currencies.manage

Parameters

NameInRequiredSchemaDescription
codequeryYesany

Responses

200Consumer currency usage count
Content-Type: application/json
{
  "code": "string",
  "count": 1
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
500Failed to load currency usage
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/admin/currency-usage?code=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/consumers/admin/remove
Auth requiredconsumers.admin.remove

Permanently remove consumer

Admin-initiated GDPR removal of a consumer (irreversible). Reverts pending outgoing gifts, cleans up family memberships, disables wallet auto-refill, redacts PII on the User and ConsumerProfile, revokes all sessions and detaches OAuth/password accounts, hard-deletes push devices and notification preferences, terminates active 1Global eSIM subscriptions and detaches Stripe payment methods, and writes an AccountDeletionWaiver retained for the financial record-retention period. Distinct from the reversible soft-delete on DELETE /consumers/admin. Requires features: consumers.admin.remove

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Consumer permanently removed
Content-Type: application/json
{
  "ok": true,
  "profileId": "00000000-0000-4000-8000-000000000000",
  "deletedAt": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Consumer not found
Content-Type: application/json
{
  "error": "string"
}
500Removal failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/consumers/admin/remove" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/consumers/intercom/token
Auth required

Issue an Intercom Identity Verification JWT

Returns a short-lived HS256 JWT signed with the Intercom Identity Verification secret. The mobile app passes this token to the Intercom SDK alongside the user id so Intercom can verify the session is legitimate.

Responses

200Signed token
Content-Type: application/json
{
  "token": "string",
  "userId": "00000000-0000-4000-8000-000000000000",
  "expiresAt": "string"
}
404User not found
Content-Type: application/json
{
  "error": "string"
}
503Intercom identity verification not configured
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/intercom/token" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/consumers/me
Auth required

Get current consumer profile

Returns the authenticated consumer profile with Covo-specific fields.

Responses

200Consumer profile
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000",
  "email": "user@example.com",
  "firstName": null,
  "lastName": null,
  "phone": null,
  "languageCode": null,
  "displayCurrency": null,
  "homeCountryCode": null,
  "travelProfile": null,
  "birthDate": null,
  "address": null,
  "billing": null,
  "active": true,
  "createdAt": "string"
}
404User not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/me" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/consumers/me
Auth required

Update consumer profile

Updates profile fields for the authenticated consumer. All fields are optional.

Request body (application/json)

{
  "firstName": null,
  "lastName": null,
  "phone": null,
  "languageCode": null,
  "displayCurrency": null,
  "homeCountryCode": null,
  "travelProfile": null,
  "birthDate": null,
  "address": null,
  "billing": null
}

Responses

200Updated profile
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000",
  "email": "user@example.com",
  "firstName": null,
  "lastName": null,
  "phone": null,
  "languageCode": null,
  "displayCurrency": null,
  "homeCountryCode": null,
  "travelProfile": null,
  "birthDate": null,
  "address": null,
  "billing": null,
  "active": true,
  "createdAt": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/consumers/me" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"firstName\": null,
  \"lastName\": null,
  \"phone\": null,
  \"languageCode\": null,
  \"displayCurrency\": null,
  \"homeCountryCode\": null,
  \"travelProfile\": null,
  \"birthDate\": null,
  \"address\": null,
  \"billing\": null
}"
DELETE/consumers/me
Auth required

Delete current consumer account

Self-service account deletion (GDPR Art. 17 / Apple 5.1.1(v)). Requires recent reauthentication via email OTP or social ID token. Reverts pending outgoing gifts, cleans up family memberships, disables wallet auto-refill, redacts PII on User and ConsumerProfile, hard-deletes push devices and notification preferences, terminates active 1Global eSIM subscriptions and detaches Stripe payment methods, and writes an AccountDeletionWaiver record retained for the financial record-retention period.

Request body (application/json)

{
  "confirm": true,
  "waiveBalance": true,
  "waiverTextVersion": "string",
  "tosVersion": "string",
  "privacyPolicyVersion": "string",
  "reauth": {
    "method": "otp",
    "code": "string"
  }
}

Responses

200Account deleted
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000",
  "deletedAt": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
403Reauthentication failed
Content-Type: application/json
{
  "error": "string"
}
404Consumer or user not found
Content-Type: application/json
{
  "error": "string"
}
500Deletion failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/consumers/me" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"confirm\": true,
  \"waiveBalance\": true,
  \"waiverTextVersion\": \"string\",
  \"tosVersion\": \"string\",
  \"privacyPolicyVersion\": \"string\",
  \"reauth\": {
    \"method\": \"otp\",
    \"code\": \"string\"
  }
}"
GET/consumers/me/country-by-ip
Auth required

Resolve the caller's country from their request IP

Returns the ISO 3166-1 alpha-2 country code inferred from the request IP, or null when it cannot be determined (private/loopback IP, lookup miss, provider failure). Best-effort: this endpoint never fails the call due to lookup errors. The mobile app should treat null as 'unknown' rather than retrying aggressively.

Responses

200Country code (or null if unresolved)
Content-Type: application/json
{
  "countryCode": null,
  "ip": null
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/me/country-by-ip" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/consumers/me/spending-cap
Auth required

Get the authenticated user personal monthly spending cap

Returns the personal cap (in EUR cents), current monthly eSIM spend, and family membership flags (isFamilyMember/isFamilyAdmin) for the authenticated consumer.

Responses

200Personal spending cap status
Content-Type: application/json
{
  "userId": "00000000-0000-4000-8000-000000000000",
  "personalSpendingCapEuroCents": null,
  "monthlySpentEuroCents": 1,
  "isFamilyMember": true,
  "isFamilyAdmin": true
}

Example

curl -X GET "https://admin.getcovo.com/api/consumers/me/spending-cap" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/consumers/me/spending-cap
Auth required

Set or clear the authenticated user personal monthly spending cap

Sets the monthly eSIM spending cap (in EUR cents) for the calling user. Pass null to clear. Rejected if the user is a non-admin family member.

Request body (application/json)

{
  "capEuroCents": null
}

Responses

200Personal spending cap updated
Content-Type: application/json
{
  "userId": "00000000-0000-4000-8000-000000000000",
  "personalSpendingCapEuroCents": null
}
400Invalid body or user is a non-admin family member
Content-Type: application/json
{
  "error": "string"
}
404Consumer profile not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/consumers/me/spending-cap" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"capEuroCents\": null
}"

Countries

Showing 6 of 6 endpoints
GET/countries/admin/countries
Auth requiredcountries.admin.list

List countries (admin)

Returns the country pricing catalog with pagination, search by code or name, and an optional blocked/allowed filter. Items include blocked-country metadata. Requires features: countries.admin.list

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
searchqueryNoany
blockedqueryNoany

Responses

200Country list
Content-Type: application/json
{
  "items": [
    {
      "code": "string",
      "name": "string",
      "flagUrl": null,
      "zone": "A",
      "pricingRating": 1,
      "pricePerGb": {
        "amountInMinorUnits": 1,
        "currency": "string"
      },
      "canRoam": true,
      "canSell": true,
      "canUseInOneGlobal": true,
      "isBlocked": true,
      "blockedSeverity": null,
      "appStoreBlocked": true,
      "apiBlocked": true,
      "smdpBlocked": true,
      "vpnAdvice": true,
      "requirePreInstall": true,
      "blockedMessage": null,
      "localizedBlockedMessages": null,
      "hasProductOfferings": true
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/countries/admin/countries?page=1&pageSize=50&sortField=code&sortDir=asc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/countries/admin/countries
Auth requiredcountries.admin.create

Create country

Creates a new country in the catalog with pricing, roaming/sell flags, and optional blocked-country metadata. Action is logged and reversible via undo (soft-deletes the new row). Requires features: countries.admin.create

Request body (application/json)

{
  "code": "string",
  "name": "string",
  "zone": "A",
  "pricingRating": 1,
  "pricePerGb": {
    "amountInMinorUnits": 1,
    "currency": "string"
  },
  "flagUrl": null,
  "canRoam": true,
  "canSell": true,
  "canUseInOneGlobal": false,
  "blockedSeverity": null,
  "blockedMessage": null,
  "localizedBlockedMessages": null
}

Responses

201Country created
Content-Type: application/json
{
  "ok": true,
  "code": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
409Country already exists
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/countries/admin/countries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"name\": \"string\",
  \"zone\": \"A\",
  \"pricingRating\": 1,
  \"pricePerGb\": {
    \"amountInMinorUnits\": 1,
    \"currency\": \"string\"
  },
  \"flagUrl\": null,
  \"canRoam\": true,
  \"canSell\": true,
  \"canUseInOneGlobal\": false,
  \"blockedSeverity\": null,
  \"blockedMessage\": null,
  \"localizedBlockedMessages\": null
}"
PUT/countries/admin/countries
Auth requiredcountries.admin.update

Update country pricing

Updates the per-GB price, expensiveness rating (1–5), roaming/sell flags, or blocked-country metadata for a country. Identified by ISO-2 code in the body `id` field. Action is logged and reversible via undo. Requires features: countries.admin.update

Request body (application/json)

{
  "id": "string",
  "blockedSeverity": null,
  "blockedMessage": null,
  "localizedBlockedMessages": null
}

Responses

200Country updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Country not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/countries/admin/countries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\",
  \"blockedSeverity\": null,
  \"blockedMessage\": null,
  \"localizedBlockedMessages\": null
}"
DELETE/countries/admin/countries
Auth requiredcountries.admin.delete

Delete country

Soft-deletes a country by ISO-2 code (passed as `id` query param). Blocks deletion when the code is still referenced by any eSIM, usage snapshot, or consumer profile. Action is logged and reversible via undo. Requires features: countries.admin.delete

Parameters

NameInRequiredSchemaDescription
idqueryYesany

Responses

200Country deleted
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Country not found
Content-Type: application/json
{
  "error": "string"
}
409Country in use by other records
Content-Type: application/json
{
  "error": "string",
  "references": {
    "esims": 1,
    "usageSnapshots": 1,
    "consumerProfiles": 1
  }
}

Example

curl -X DELETE "https://admin.getcovo.com/api/countries/admin/countries?id=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/countries/blocked

List blocked countries

Returns countries with known eSIM-related restrictions (blocked apps/APIs/SM-DP+) and pre-travel enforcement metadata. Unauthenticated; cached for 24 hours. Read by the mobile app on launch.

Responses

200Blocked country list
Content-Type: application/json
{
  "countries": [
    {
      "countryCode": "string",
      "name": "string",
      "severity": "full",
      "restrictions": {
        "appStoreBlocked": true,
        "apiBlocked": true,
        "smdpBlocked": true
      },
      "vpnAdvice": true,
      "requirePreInstall": true,
      "message": "string",
      "localizedMessages": null
    }
  ]
}
500Failed to load blocked countries
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/countries/blocked" \
  -H "Accept: application/json"
GET/countries/countries
Auth requiredcountries.list

List countries

Returns the catalog of supported countries with per-GB pricing, expensiveness rating (1–5), zone, and roaming/sell flags. Supports pagination and search by code or name. Requires features: countries.list

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
searchqueryNoany

Responses

200Country list
Content-Type: application/json
{
  "countries": [
    {
      "code": "string",
      "name": "string",
      "flagUrl": null,
      "zone": "A",
      "pricingRating": 1,
      "pricePerGb": {
        "amountInMinorUnits": 1,
        "currency": "string"
      },
      "canRoam": true,
      "canSell": true,
      "canUseInOneGlobal": true
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/countries/countries?page=1&pageSize=50&sortField=code&sortDir=asc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Dashboards

Showing 9 of 9 endpoints
GET/dashboards/layout
Auth requireddashboards.view

Load the current dashboard layout

Returns the saved widget layout together with the widgets the current user is allowed to place. Requires features: dashboards.view

Responses

200Current dashboard layout and available widgets.
Content-Type: application/json
{
  "layout": {
    "items": [
      {
        "id": "00000000-0000-4000-8000-000000000000",
        "widgetId": "string",
        "order": 1
      }
    ]
  },
  "allowedWidgetIds": [
    "string"
  ],
  "canConfigure": true,
  "context": {
    "userId": "00000000-0000-4000-8000-000000000000",
    "tenantId": null,
    "organizationId": null,
    "userName": null,
    "userEmail": null,
    "userLabel": "string"
  },
  "widgets": [
    {
      "id": "string",
      "title": "string",
      "description": null,
      "defaultSize": "sm",
      "defaultEnabled": true,
      "defaultSettings": null,
      "features": [
        "string"
      ],
      "moduleId": "string",
      "icon": null,
      "loaderKey": "string",
      "supportsRefresh": true
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/dashboards/layout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/layout
Auth requireddashboards.configure

Persist dashboard layout changes

Saves the provided widget ordering, sizes, and settings for the current user. Requires features: dashboards.configure

Request body (application/json)

{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "widgetId": "string",
      "order": 1
    }
  ]
}

Responses

200Layout updated successfully.
Content-Type: application/json
{
  "ok": true
}
400Invalid layout payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/dashboards/layout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"items\": [
    {
      \"id\": \"00000000-0000-4000-8000-000000000000\",
      \"widgetId\": \"string\",
      \"order\": 1
    }
  ]
}"
PATCH/dashboards/layout/{itemId}
Auth requireddashboards.configure

Update a dashboard layout item

Adjusts the size or settings for a single widget within the dashboard layout. Requires features: dashboards.configure

Parameters

NameInRequiredSchemaDescription
itemIdpathYesany

Request body (application/json)

{}

Responses

200Layout item updated.
Content-Type: application/json
{
  "ok": true
}
400Invalid payload or missing item id
Content-Type: application/json
{
  "error": "string"
}
404Item not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/dashboards/layout/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
GET/dashboards/roles/widgets
Auth requireddashboards.admin.assign-widgets

Fetch widget assignments for a role

Returns the widgets explicitly assigned to the given role together with the evaluation scope. Requires features: dashboards.admin.assign-widgets

Parameters

NameInRequiredSchemaDescription
roleIdqueryYesany
tenantIdqueryNoany
organizationIdqueryNoany

Responses

200Current widget configuration for the role.
Content-Type: application/json
{
  "widgetIds": [
    "string"
  ],
  "hasCustom": true,
  "scope": {
    "tenantId": null,
    "organizationId": null
  }
}
400Missing role identifier
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dashboards/roles/widgets?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/roles/widgets
Auth requireddashboards.admin.assign-widgets

Update widgets assigned to a role

Persists the widget list for a role within the provided tenant and organization scope. Requires features: dashboards.admin.assign-widgets

Request body (application/json)

{
  "roleId": "00000000-0000-4000-8000-000000000000",
  "widgetIds": [
    "string"
  ]
}

Responses

200Widgets updated successfully.
Content-Type: application/json
{
  "ok": true,
  "widgetIds": [
    "string"
  ]
}
400Invalid payload or unknown widgets
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/dashboards/roles/widgets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"roleId\": \"00000000-0000-4000-8000-000000000000\",
  \"widgetIds\": [
    \"string\"
  ]
}"
GET/dashboards/users/widgets
Auth requireddashboards.admin.assign-widgets

Read widget overrides for a user

Returns the widgets inherited and explicitly configured for the requested user within the current scope. Requires features: dashboards.admin.assign-widgets

Parameters

NameInRequiredSchemaDescription
userIdqueryYesany
tenantIdqueryNoany
organizationIdqueryNoany

Responses

200Widget settings for the user.
Content-Type: application/json
{
  "mode": "inherit",
  "widgetIds": [
    "string"
  ],
  "hasCustom": true,
  "effectiveWidgetIds": [
    "string"
  ],
  "scope": {
    "tenantId": null,
    "organizationId": null
  }
}
400Missing user identifier
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dashboards/users/widgets?userId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/users/widgets
Auth requireddashboards.admin.assign-widgets

Update user-specific dashboard widgets

Sets the widget override mode and allowed widgets for a user. Passing `mode: inherit` clears overrides. Requires features: dashboards.admin.assign-widgets

Request body (application/json)

{
  "userId": "00000000-0000-4000-8000-000000000000",
  "mode": "inherit",
  "widgetIds": [
    "string"
  ]
}

Responses

200Overrides saved.
Content-Type: application/json
{
  "ok": true,
  "mode": "inherit",
  "widgetIds": [
    "string"
  ]
}
400Invalid payload or unknown widgets
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/dashboards/users/widgets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"userId\": \"00000000-0000-4000-8000-000000000000\",
  \"mode\": \"inherit\",
  \"widgetIds\": [
    \"string\"
  ]
}"
GET/dashboards/widgets/catalog
Auth requireddashboards.admin.assign-widgets

List available dashboard widgets

Returns the catalog of widgets that modules expose, including defaults and feature requirements. Requires features: dashboards.admin.assign-widgets

Responses

200Widgets available for assignment.
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "description": null,
      "defaultSize": "sm",
      "defaultEnabled": true,
      "defaultSettings": null,
      "features": [
        "string"
      ],
      "moduleId": "string",
      "icon": null,
      "loaderKey": "string",
      "supportsRefresh": true
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/dashboards/widgets/catalog" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dashboards/widgets/data
Auth requiredanalytics.view

Fetch aggregated data for dashboard widgets

Executes an aggregation query against the specified entity type and returns the result. Supports date range filtering, grouping, and period-over-period comparison. Requires features: analytics.view

Request body (application/json)

{
  "entityType": "string",
  "metric": {
    "field": "string",
    "aggregate": "count"
  }
}

Responses

200Aggregated data for the widget.
Content-Type: application/json
{
  "value": null,
  "data": [
    {
      "value": null
    }
  ],
  "metadata": {
    "fetchedAt": "string",
    "recordCount": 1
  }
}
400Invalid request payload
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/dashboards/widgets/data" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\",
  \"metric\": {
    \"field\": \"string\",
    \"aggregate\": \"count\"
  }
}"

Admin · Data Exports

Showing 6 of 6 endpoints
GET/data_exports/admin
Auth requireddata_exports.admin.list

List data export requests (admin)

Returns a paginated list of data-export requests scoped to the caller tenant/organization. Supports filtering by status (csv) and channel (csv), free-text search on the subject by email or name, and sorting by created/assembled/delivered time. Requires features: data_exports.admin.list

Parameters

NameInRequiredSchemaDescription
statusqueryYesany
channelqueryYesany
searchqueryNoany
pagequeryNoany
pageSizequeryNoany
sortqueryNoany

Responses

200Data export request list
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "status": "requested",
      "channel": "self_service",
      "subjectUserId": null,
      "rejectionReason": null,
      "createdAt": "string",
      "assembledAt": null,
      "deliveredAt": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/data_exports/admin?page=1&pageSize=50&sort=createdAt%3Adesc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/data_exports/admin
Auth requireddata_exports.admin.trigger

Trigger a data export for a chosen user (admin)

Creates a data-export request on the `admin_initiated` channel for an existing consumer in the caller tenant/organization and enqueues automated assembly. Delivery still waits for the human Send gate. Fails with 404 if the subject is not a live consumer in scope. Requires features: data_exports.admin.trigger

Request body (application/json)

{
  "subjectUserId": "00000000-0000-4000-8000-000000000000"
}

Responses

201Export request created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "requested"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Subject not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/data_exports/admin" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"subjectUserId\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/data_exports/admin/{id}
Auth requireddata_exports.admin.view

Get a data export request (admin)

Returns a single data-export request scoped to the caller tenant/organization, including the resolved subject (minimal profile), assembly/bundle status, applied override, and rejection reason. Requires features: data_exports.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Data export request detail
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "requested",
  "channel": "self_service",
  "subjectUserId": null,
  "subject": null,
  "identifierType": null,
  "identifierValue": null,
  "overrideItems": null,
  "rejectionReason": null,
  "hasBundle": true,
  "linkExpiresAt": null,
  "requestedByUserId": null,
  "sentByUserId": null,
  "assembledAt": null,
  "deliveredAt": null,
  "createdAt": "string",
  "updatedAt": "string"
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Request not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/data_exports/admin/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/data_exports/admin/{id}/preview
Auth requireddata_exports.admin.preview

Preview/download an assembled data export bundle (admin)

Serves the assembled zip bundle (PDF + CSV/JSON) for admin review before sending, scoped to the caller tenant/organization. S3-backed partitions return a 302 redirect to a short-lived presigned URL; on-disk dev/test partitions stream the zip inline. Available from the `assembled` state onward. Fails with 409 if the bundle is not yet assembled. Requires features: data_exports.admin.preview

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Zip bundle (streamed inline for on-disk partitions)
Content-Type: application/zip
string
302Redirect to a short-lived presigned download URL
Content-Type: application/json
"string"
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Request not found
Content-Type: application/json
{
  "error": "string"
}
409Bundle not assembled
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/data_exports/admin/00000000-0000-4000-8000-000000000000/preview" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/data_exports/admin/{id}/reject
Auth requireddata_exports.admin.reject

Reject a data export request (admin)

Closes a data-export request without fulfilment and records the reason (internal-only, never exported to the subject per Art. 15(4)). Valid from any pre-delivery state; transitions the request to `rejected`. Fails with 409 if the request is already delivered or rejected. Requires features: data_exports.admin.reject

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "reason": "string"
}

Responses

200Request rejected
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "rejected"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Request not found
Content-Type: application/json
{
  "error": "string"
}
409Request cannot be rejected in its current state
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/data_exports/admin/00000000-0000-4000-8000-000000000000/reject" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"reason\": \"string\"
}"
POST/data_exports/admin/{id}/send
Auth requireddata_exports.admin.send

Review and send an assembled data export (admin)

Releases an already-assembled export to the subject: mints the secure 24h download token, fires the in-app "export ready" notification, and transitions the request from `assembled` to `delivered`. Fails with 409 if the request is not in the `assembled` state with a stored bundle. Requires features: data_exports.admin.send

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Export delivered
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "delivered"
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Request not found
Content-Type: application/json
{
  "error": "string"
}
409Export not ready to send
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/data_exports/admin/00000000-0000-4000-8000-000000000000/send" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Dictionaries

Showing 11 of 11 endpoints
GET/dictionaries
Auth requireddictionaries.view

List dictionaries

Returns dictionaries accessible to the current organization, optionally including inactive records. Requires features: dictionaries.view

Parameters

NameInRequiredSchemaDescription
includeInactivequeryNoany

Responses

200Dictionary collection.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "key": "string",
      "name": "string",
      "description": null,
      "isSystem": true,
      "isActive": true,
      "managerVisibility": null,
      "organizationId": null,
      "createdAt": "string",
      "updatedAt": null
    }
  ]
}
500Failed to load dictionaries
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dictionaries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dictionaries
Auth requireddictionaries.manage

Create dictionary

Registers a dictionary scoped to the current organization. Requires features: dictionaries.manage

Request body (application/json)

{
  "key": "string",
  "name": "string"
}

Responses

201Dictionary created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "key": "string",
  "name": "string",
  "description": null,
  "isSystem": true,
  "isActive": true,
  "managerVisibility": null,
  "organizationId": null,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
409Dictionary key already exists
Content-Type: application/json
{
  "error": "string"
}
500Failed to create dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/dictionaries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"key\": \"string\",
  \"name\": \"string\"
}"
GET/dictionaries/{dictionaryId}
Auth requireddictionaries.view

Get dictionary

Returns details for the specified dictionary, including inheritance flags. Requires features: dictionaries.view

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany

Responses

200Dictionary details.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "key": "string",
  "name": "string",
  "description": null,
  "isSystem": true,
  "isActive": true,
  "managerVisibility": null,
  "organizationId": null,
  "createdAt": "string",
  "updatedAt": null
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/dictionaries/{dictionaryId}
Auth requireddictionaries.manage

Update dictionary

Updates mutable attributes of the dictionary. Currency dictionaries are protected from modification. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany

Request body (application/json)

{}

Responses

200Dictionary updated.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "key": "string",
  "name": "string",
  "description": null,
  "isSystem": true,
  "isActive": true,
  "managerVisibility": null,
  "organizationId": null,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed or protected dictionary
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
409Dictionary key already exists
Content-Type: application/json
{
  "error": "string"
}
500Failed to update dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
DELETE/dictionaries/{dictionaryId}
Auth requireddictionaries.manage

Delete dictionary

Soft deletes the dictionary unless it is the protected currency dictionary. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany

Responses

200Dictionary archived.
Content-Type: application/json
{
  "ok": true
}
400Protected dictionary cannot be deleted
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to delete dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/dictionaries/{dictionaryId}/entries
Auth requireddictionaries.view

List dictionary entries

Returns entries for the specified dictionary ordered by position. Requires features: dictionaries.view

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany

Responses

200Dictionary entries.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "value": "string",
      "label": "string",
      "color": null,
      "icon": null,
      "position": 1,
      "isDefault": true,
      "createdAt": "string",
      "updatedAt": null
    }
  ]
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load dictionary entries
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000/entries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dictionaries/{dictionaryId}/entries
Auth requireddictionaries.manage

Create dictionary entry

Creates a new entry in the specified dictionary. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany

Request body (application/json)

{
  "value": "string",
  "color": null,
  "icon": null
}

Responses

201Dictionary entry created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "value": "string",
  "label": "string",
  "color": null,
  "icon": null,
  "position": 1,
  "isDefault": true,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to create dictionary entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000/entries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"value\": \"string\",
  \"color\": null,
  \"icon\": null
}"
PATCH/dictionaries/{dictionaryId}/entries/{entryId}
Auth requireddictionaries.manage

Update dictionary entry

Updates the specified dictionary entry using the command bus pipeline. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany
entryIdpathYesany

Request body (application/json)

{
  "color": null,
  "icon": null
}

Responses

200Dictionary entry updated.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "value": "string",
  "label": "string",
  "color": null,
  "icon": null,
  "position": 1,
  "isDefault": true,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary or entry not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to update entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"color\": null,
  \"icon\": null
}"
DELETE/dictionaries/{dictionaryId}/entries/{entryId}
Auth requireddictionaries.manage

Delete dictionary entry

Deletes the specified dictionary entry via the command bus. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany
entryIdpathYesany

Responses

200Entry deleted.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary or entry not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to delete entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dictionaries/{dictionaryId}/entries/reorder
Auth requireddictionaries.manage

Reorder dictionary entries

Updates the position of dictionary entries for drag-and-drop reordering. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany

Request body (application/json)

{
  "entries": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "position": 1
    }
  ]
}

Responses

200Entries reordered.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to reorder entries
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/reorder" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entries\": [
    {
      \"id\": \"00000000-0000-4000-8000-000000000000\",
      \"position\": 1
    }
  ]
}"
POST/dictionaries/{dictionaryId}/entries/set-default
Auth requireddictionaries.manage

Set default dictionary entry

Marks the specified entry as the default for this dictionary, clearing any previous default. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany

Request body (application/json)

{
  "entryId": "00000000-0000-4000-8000-000000000000"
}

Responses

200Default entry set.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary or entry not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to set default entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/set-default" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entryId\": \"00000000-0000-4000-8000-000000000000\"
}"

Directory

Showing 9 of 9 endpoints
GET/directory/organization-switcher
Auth required

Load organization switcher menu

Returns the hierarchical menu of organizations the current user may switch to within the active tenant.

Responses

200Organization switcher payload.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "depth": 1,
      "selectable": true,
      "children": []
    }
  ],
  "selectedId": null,
  "canManage": true,
  "canViewAllOrganizations": true,
  "tenantId": null,
  "tenants": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "isActive": true
    }
  ],
  "isSuperAdmin": true
}

Example

curl -X GET "https://admin.getcovo.com/api/directory/organization-switcher" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/directory/organizations
Auth requireddirectory.organizations.view

List organizations

Returns organizations using options, tree, or paginated manage view depending on the `view` parameter. Requires features: directory.organizations.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
searchqueryNoany
viewqueryNoany
idsqueryNoany
tenantIdqueryNoany
includeInactivequeryNoany
statusqueryNoany

Responses

200Organization data for the requested view.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "parentId": null,
      "parentName": null,
      "tenantId": null,
      "tenantName": null,
      "rootId": null,
      "treePath": null
    }
  ]
}
400Invalid query or tenant scope
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/directory/organizations?page=1&pageSize=50&view=options" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/directory/organizations
Auth requireddirectory.organizations.manage

Create organization

Creates a new organization within a tenant and optionally assigns hierarchy relationships. Requires features: directory.organizations.manage

Request body (application/json)

{
  "name": "string",
  "slug": null,
  "parentId": null
}

Responses

201Organization created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"slug\": null,
  \"parentId\": null
}"
PUT/directory/organizations
Auth requireddirectory.organizations.manage

Update organization

Updates organization details and hierarchy assignments. Requires features: directory.organizations.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "slug": null,
  "parentId": null
}

Responses

200Organization updated.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"slug\": null,
  \"parentId\": null
}"
DELETE/directory/organizations
Auth requireddirectory.organizations.manage

Delete organization

Soft deletes an organization identified by id. Requires features: directory.organizations.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Organization deleted.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/directory/tenants
Auth requireddirectory.tenants.view

List tenants

Returns tenants visible to the current user with optional search and pagination. Requires features: directory.tenants.view

Parameters

NameInRequiredSchemaDescription
idqueryNoany
pagequeryNoany
pageSizequeryNoany
searchqueryNoany
sortFieldqueryNoany
sortDirqueryNoany
isActivequeryNoany

Responses

200Paged list of tenants.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "isActive": true,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/directory/tenants?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/directory/tenants
Auth requireddirectory.tenants.manage

Create tenant

Creates a new tenant and returns its identifier. Requires features: directory.tenants.manage

Request body (application/json)

{
  "name": "string"
}

Responses

201Tenant created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
PUT/directory/tenants
Auth requireddirectory.tenants.manage

Update tenant

Updates tenant properties such as name or activation state. Requires features: directory.tenants.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Tenant updated.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/directory/tenants
Auth requireddirectory.tenants.manage

Delete tenant

Soft deletes the tenant identified by id. Requires features: directory.tenants.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Tenant removed.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"

DNS Filtering Admin

Showing 6 of 6 endpoints
GET/dns_filtering/admin/child-safety
Auth requireddns_filtering.admin.list

List families with their child-safety state

Returns paginated families with content/safe-web flags, derived protectionStatus, child count, and last updated timestamp. Owner email and name are joined. Free-text search matches the family owner by email or name. Requires features: dns_filtering.admin.list

Parameters

NameInRequiredSchemaDescription
searchqueryNoany
protectionStatusqueryNoany
limitqueryNoany
offsetqueryNoany

Responses

200List of families
Content-Type: application/json
{
  "items": [
    {
      "familyId": "string",
      "ownerUserId": "string",
      "ownerEmail": "string",
      "ownerName": null,
      "contentFilterEnabled": true,
      "safeWebEnabled": true,
      "protectionStatus": "fully",
      "childCount": 1,
      "lastUpdatedAt": null
    }
  ],
  "total": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/admin/child-safety?limit=50&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/dns_filtering/admin/child-safety/{familyId}
Auth requireddns_filtering.admin.list

Get child-safety detail for a family

Returns the family child-safety settings, the owner, and the list of affected child users (with email + name). Requires features: dns_filtering.admin.list

Parameters

NameInRequiredSchemaDescription
familyIdpathYesany

Responses

200Child safety detail
Content-Type: application/json
{
  "familyId": "string",
  "ownerUserId": "string",
  "ownerEmail": "string",
  "ownerName": null,
  "contentFilterEnabled": true,
  "safeWebEnabled": true,
  "protectionStatus": "fully",
  "lastUpdatedAt": null,
  "children": [
    {
      "userId": "string",
      "email": null,
      "name": null
    }
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/admin/child-safety/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/dns_filtering/admin/config
Auth requireddns_filtering.admin.list

Get DNS filtering pricing and DNS provider catalog

Requires features: dns_filtering.admin.list

Responses

200DNS filtering config
Content-Type: application/json
{
  "networkTurboPriceEuroCents": 1,
  "providers": [
    {
      "id": "string",
      "label": null,
      "dohUrl": "https://example.com/resource",
      "dnsIpPrimary": "string",
      "dnsIpSecondary": "string",
      "isActive": true
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/admin/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dns_filtering/admin/config
Auth requireddns_filtering.admin.config

Update DNS filtering pricing

Updates the singleton DnsFilteringConfig row's networkTurboPriceEuroCents. Action is logged with before/after snapshots for undo. Requires features: dns_filtering.admin.config

Request body (application/json)

{
  "networkTurboPriceEuroCents": 1
}

Responses

200Updated DNS filtering config
Content-Type: application/json
{
  "networkTurboPriceEuroCents": 1,
  "providers": [
    {
      "id": "string",
      "label": null,
      "dohUrl": "https://example.com/resource",
      "dnsIpPrimary": "string",
      "dnsIpSecondary": "string",
      "isActive": true
    }
  ]
}
400Invalid body
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/dns_filtering/admin/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"networkTurboPriceEuroCents\": 1
}"
GET/dns_filtering/admin/network-turbo
Auth requireddns_filtering.admin.list

List Network Turbo records across the tenant

Returns users with Network Turbo records, with their effective state plus per-source breakdown (self / family-admin). Supports filtering by status, fundedBy, autoRenewal, familyId, userId, and free-text user search by email or name. Requires features: dns_filtering.admin.list

Parameters

NameInRequiredSchemaDescription
searchqueryNoany
statusqueryNoany
fundedByqueryNoany
autoRenewalqueryNoany
familyIdqueryNoany
userIdqueryNoany
limitqueryNoany
offsetqueryNoany

Responses

200List of users with Network Turbo records
Content-Type: application/json
{
  "items": [
    {
      "userId": "string",
      "userEmail": "string",
      "userName": null,
      "familyId": null,
      "effectiveEnabled": true,
      "effectiveFundedBy": null,
      "effectivePaidUntil": null,
      "autoRenewalEnabled": true,
      "self": {
        "state": "string",
        "paidUntil": null,
        "bankedUntil": null,
        "pausedAt": null,
        "autoRenewalEnabled": true
      },
      "familyAdmin": {
        "state": "string",
        "paidUntil": null,
        "bankedUntil": null,
        "pausedAt": null,
        "autoRenewalEnabled": true
      }
    }
  ],
  "total": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/admin/network-turbo?limit=50&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/dns_filtering/admin/network-turbo/{userId}
Auth requireddns_filtering.admin.list

Get Network Turbo detail + resolved DNS config for a user

Returns the full per-source Network Turbo breakdown plus the user's currently-resolved DNS provider/reason/enforcedBy. Requires features: dns_filtering.admin.list

Parameters

NameInRequiredSchemaDescription
userIdpathYesany

Responses

200Network Turbo detail
Content-Type: application/json
{
  "userId": "string",
  "userEmail": "string",
  "userName": null,
  "familyId": null,
  "networkTurbo": {
    "enabled": true,
    "fundedBy": null,
    "paidUntil": null,
    "autoRenewalEnabled": true,
    "self": {
      "state": "string",
      "paidUntil": null,
      "bankedUntil": null,
      "pausedAt": null,
      "autoRenewalEnabled": true
    },
    "familyAdmin": {
      "state": "string",
      "paidUntil": null,
      "bankedUntil": null,
      "pausedAt": null,
      "autoRenewalEnabled": true
    }
  },
  "dnsConfig": null
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/dns_filtering/admin/network-turbo/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Entities

Showing 17 of 17 endpoints
GET/entities/definitions
Auth required

List active custom field definitions

Returns active custom field definitions for the supplied entity ids, respecting tenant scope and tombstones.

Parameters

NameInRequiredSchemaDescription
entityIdqueryNoany
entityIdsqueryNoany
fieldsetqueryNoany

Responses

200Definition list
Content-Type: application/json
{
  "items": [
    {
      "key": "string",
      "kind": "string",
      "label": "string",
      "entityId": "string"
    }
  ]
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/definitions
Auth requiredentities.definitions.manage

Upsert custom field definition

Creates or updates a custom field definition for the current tenant/org scope. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string",
  "key": "string",
  "kind": "text"
}

Responses

200Definition saved
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "key": "string",
    "kind": "string",
    "configJson": {}
  }
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\",
  \"kind\": \"text\"
}"
DELETE/entities/definitions
Auth requiredentities.definitions.manage

Soft delete custom field definition

Marks the specified definition inactive and tombstones it for the current scope. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string",
  "key": "string"
}

Responses

200Definition deleted
Content-Type: application/json
{
  "ok": true
}
400Missing entity id or key
Content-Type: application/json
{
  "error": "string"
}
404Definition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\"
}"
POST/entities/definitions.batch
Auth requiredentities.definitions.manage

Save multiple custom field definitions

Creates or updates multiple definitions for a single entity in one transaction. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string",
  "definitions": [
    {
      "key": "string",
      "kind": "text"
    }
  ]
}

Responses

200Definitions saved
Content-Type: application/json
{
  "ok": true
}
400Validation error
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/entities/definitions.batch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"definitions\": [
    {
      \"key\": \"string\",
      \"kind\": \"text\"
    }
  ]
}"
GET/entities/definitions.manage
Auth requiredentities.definitions.manage

Get management snapshot

Returns scoped custom field definitions (including inactive tombstones) for administration interfaces. Requires features: entities.definitions.manage

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany

Responses

200Scoped definitions and deleted keys
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "key": "string",
      "kind": "string",
      "configJson": null,
      "organizationId": null,
      "tenantId": null
    }
  ],
  "deletedKeys": [
    "string"
  ]
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/entities/definitions.manage?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/definitions.restore
Auth requiredentities.definitions.manage

Restore definition

Reactivates a previously soft-deleted definition within the current tenant/org scope. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string",
  "key": "string"
}

Responses

200Definition restored
Content-Type: application/json
{
  "ok": true
}
400Missing entity id or key
Content-Type: application/json
{
  "error": "string"
}
404Definition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/entities/definitions.restore" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\"
}"
GET/entities/encryption
Auth requiredentities.definitions.manage

Fetch encryption map

Returns the encrypted field map for the current tenant/organization scope. Requires features: entities.definitions.manage

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany

Responses

200Map
Content-Type: application/json
{
  "entityId": "string",
  "fields": [
    {
      "field": "string",
      "hashField": null
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/entities/encryption?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/encryption
Auth requiredentities.definitions.manage

Upsert encryption map

Creates or updates the encryption map for the current tenant/organization scope. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string",
  "tenantId": null,
  "organizationId": null,
  "fields": [
    {
      "field": "string",
      "hashField": null
    }
  ]
}

Responses

200Saved
Content-Type: application/json
{
  "ok": true
}

Example

curl -X POST "https://admin.getcovo.com/api/entities/encryption" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"tenantId\": null,
  \"organizationId\": null,
  \"fields\": [
    {
      \"field\": \"string\",
      \"hashField\": null
    }
  ]
}"
GET/entities/entities
Auth required

List available entities

Returns generated and custom entities scoped to the caller with field counts per entity.

Responses

200List of entities
Content-Type: application/json
{
  "items": [
    {
      "entityId": "string",
      "source": "code",
      "label": "string",
      "count": 1
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/entities
Auth requiredentities.definitions.manage

Upsert custom entity

Creates or updates a tenant/org scoped custom entity definition. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string",
  "label": "string",
  "description": null,
  "showInSidebar": false
}

Responses

200Entity saved
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "entityId": "string",
    "label": "string"
  }
}
400Validation error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"label\": \"string\",
  \"description\": null,
  \"showInSidebar\": false
}"
DELETE/entities/entities
Auth requiredentities.definitions.manage

Soft delete custom entity

Marks the specified custom entity inactive within the current scope. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string"
}

Responses

200Entity deleted
Content-Type: application/json
{
  "ok": true
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}
404Entity not found in scope
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\"
}"
GET/entities/records
Auth requiredentities.records.view

List records

Returns paginated records for the supplied entity. Supports custom field filters, exports, and soft-delete toggles. Requires features: entities.records.view

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
withDeletedqueryNoany
formatqueryNoany
exportScopequeryNoany
export_scopequeryNoany
allqueryNoany
fullqueryNoany

Responses

200Paginated records
Content-Type: application/json
{
  "items": [
    {}
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/entities/records?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/records
Auth requiredentities.records.manage

Create record

Creates a record for the given entity. When `recordId` is omitted or not a UUID the data engine will generate one automatically. Requires features: entities.records.manage

Request body (application/json)

{
  "entityId": "string",
  "values": {}
}

Responses

200Record created
Content-Type: application/json
{
  "ok": true
}
400Validation failure
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"values\": {}
}"
PUT/entities/records
Auth requiredentities.records.manage

Update record

Updates an existing record. If the provided recordId is not a UUID the record will be created instead to support optimistic flows. Requires features: entities.records.manage

Request body (application/json)

{
  "entityId": "string",
  "recordId": "string",
  "values": {}
}

Responses

200Record updated
Content-Type: application/json
{
  "ok": true
}
400Validation failure
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\",
  \"values\": {}
}"
DELETE/entities/records
Auth requiredentities.records.manage

Delete record

Soft deletes the specified record within the current tenant/org scope. Requires features: entities.records.manage

Request body (application/json)

{
  "entityId": "string",
  "recordId": "string"
}

Responses

200Record deleted
Content-Type: application/json
{
  "ok": true
}
400Missing entity id or record id
Content-Type: application/json
{
  "error": "string"
}
404Record not found
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\"
}"
GET/entities/relations/options
Auth requiredentities.definitions.view

List relation options

Returns up to 200 option entries for populating relation dropdowns, automatically resolving label fields when omitted. Requires features: entities.definitions.view

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany
labelFieldqueryNoany
qqueryNoany
idsqueryNoany
routeContextFieldsqueryNoany

Responses

200Option list
Content-Type: application/json
{
  "items": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/entities/relations/options?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/entities/sidebar-entities
Auth required

Get sidebar entities

Returns custom entities flagged with `showInSidebar` for the current tenant/org scope.

Responses

200Sidebar entities for navigation
Content-Type: application/json
{
  "items": [
    {
      "entityId": "string",
      "label": "string",
      "href": "string"
    }
  ]
}

Example

curl -X GET "https://admin.getcovo.com/api/entities/sidebar-entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

eSIM Dashboards

Showing 1 of 1 endpoints
GET/esims/dashboards/active-count
Auth requiredanalytics.viewesims.admin.list

Active eSIM count

Returns the count of eSIMs currently in status=active scoped to the caller's tenant/organization, plus the count at the start of the requested date-range preset (default last_30_days; approximated by currently-active eSIMs that already existed before the cutoff). Requires features: analytics.view, esims.admin.list

Parameters

NameInRequiredSchemaDescription
presetqueryNoany

Responses

200Active eSIM count with monthly comparison
Content-Type: application/json
{
  "value": 1,
  "comparison": null,
  "fetchedAt": "string"
}
500Failed to load active eSIM count
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/esims/dashboards/active-count" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Webhooks

Showing 2 of 2 endpoints
POST/esims/webhooks/1global

Receive 1Global event notifications

Public endpoint secured by Basic Authentication. Handles eSIM lifecycle events from 1Global Connect API.

Request body (application/json)

{
  "id": "string",
  "type": "string",
  "created_at": "string"
}

Responses

200Event received and processed
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Authentication failed
Content-Type: application/json
{
  "error": "string"
}
413Payload too large
Content-Type: application/json
{
  "error": "string"
}
500Processing failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/esims/webhooks/1global" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\",
  \"type\": \"string\",
  \"created_at\": \"string\"
}"
POST/payments/webhooks/stripe

Receive Stripe webhook events

Public endpoint secured by Stripe signature verification. Claims the event durably, logs an audit row, and emits an internal payments.stripe.* event for async processing by subscribers.

Responses

200Event accepted (handled, duplicate, or unhandled)
Content-Type: application/json
"string"
400Invalid signature, missing header, or invalid JSON
Content-Type: application/json
"string"
413Payload too large
Content-Type: application/json
"string"
500Processing failed
Content-Type: application/json
"string"

Example

curl -X POST "https://admin.getcovo.com/api/payments/webhooks/stripe" \
  -H "Accept: application/json"

Families Admin

Showing 7 of 7 endpoints
GET/families/admin
Auth requiredfamilies.admin.list

List all families

Returns a paginated list of all families with owner enrichment. The optional search query matches the family owner or any member by email or name (and by the admin-set member name). Requires features: families.admin.list

Parameters

NameInRequiredSchemaDescription
limitqueryNoany
offsetqueryNoany
searchqueryNoany

Responses

200Family list
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "ownerUserId": "00000000-0000-4000-8000-000000000000",
      "ownerEmail": "string",
      "ownerName": "string",
      "memberCount": 1,
      "invitationCount": 1,
      "createdAt": "string"
    }
  ],
  "total": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/families/admin?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/families/admin/{id}
Auth requiredfamilies.admin.view

Get family detail

Returns a single family with owner enrichment and full member list. Each member includes monthlySpentEuroCents (eSIM spend for the current calendar month in UTC; a live sum with no stored reset). No tenant scope restriction. Requires features: families.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Family detail
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "ownerUserId": "00000000-0000-4000-8000-000000000000",
  "ownerEmail": "string",
  "ownerName": "string",
  "memberCount": 1,
  "invitationCount": 1,
  "createdAt": "string",
  "updatedAt": "string",
  "deletedAt": null,
  "members": [
    {
      "userId": "00000000-0000-4000-8000-000000000000",
      "email": "string",
      "name": "string",
      "invitedName": null,
      "role": "admin",
      "spendingCapEuroCents": null,
      "monthlySpentEuroCents": 1,
      "joinedAt": "string"
    }
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/families/admin/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/families/admin/{id}
Auth requiredfamilies.admin.delete

Admin delete family

Soft-deletes a family and all its members. No owner check — admin only. Requires features: families.admin.delete

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Family deleted
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "removedUserIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/families/admin/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/families/admin/{id}/invitations
Auth requiredfamilies.admin.view

List family invitations (admin)

Returns all invitation codes for any family. No owner check. Shows all invitations including revoked ones. Requires features: families.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Invitation list
Content-Type: application/json
{
  "invitations": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "invitedName": null,
      "createdByUserId": "00000000-0000-4000-8000-000000000000",
      "usedByConsumerId": null,
      "usedAt": null,
      "expiresAt": null,
      "revokedAt": null,
      "createdAt": "string"
    }
  ]
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/families/admin/00000000-0000-4000-8000-000000000000/invitations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/families/admin/{id}/invitations/{code}
Auth requiredfamilies.admin.invitations.revoke

Admin revoke a family invitation

Feature-gated admin endpoint. Revokes any invitation from any family without owner check. Cannot revoke an already-used or already-revoked invitation. Requires features: families.admin.invitations.revoke

Parameters

NameInRequiredSchemaDescription
idpathYesany
codepathYesany

Responses

200Invitation revoked
Content-Type: application/json
{
  "code": "string",
  "revokedAt": "string"
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Family or invitation not found
Content-Type: application/json
{
  "error": "string"
}
409Invitation already revoked or already used
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/families/admin/00000000-0000-4000-8000-000000000000/invitations/string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/families/admin/{id}/members/{userId}
Auth requiredfamilies.admin.members.update

Admin update a family member

Superadmin-only. Updates any member's display name, role, and/or spending cap in a single call without owner check. Only provided fields are changed. Role is restricted to "member" or "child"; the family owner's role and cap cannot be changed. Emits families.family-member.role-changed and/or families.family-member.cap-changed when those fields change. Requires features: families.admin.members.update

Parameters

NameInRequiredSchemaDescription
idpathYesany
userIdpathYesany

Request body (application/json)

{
  "spendingCapEuroCents": null
}

Responses

200Member updated
Content-Type: application/json
{
  "familyId": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000",
  "invitedName": null,
  "role": "admin",
  "spendingCapEuroCents": null
}
400Invalid params, invalid/empty body, or cannot set role/cap for the family owner
Content-Type: application/json
{
  "error": "string"
}
404Family or member not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/families/admin/00000000-0000-4000-8000-000000000000/members/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"spendingCapEuroCents\": null
}"
DELETE/families/admin/{id}/members/{userId}
Auth requiredfamilies.admin.members.remove

Admin remove a family member

Superadmin-only. Removes any member from any family without owner check. The owner cannot be removed — delete the family instead. Requires features: families.admin.members.remove

Parameters

NameInRequiredSchemaDescription
idpathYesany
userIdpathYesany

Responses

200Member removed
Content-Type: application/json
{
  "familyId": "00000000-0000-4000-8000-000000000000",
  "userId": "00000000-0000-4000-8000-000000000000"
}
400Invalid params or cannot remove the owner
Content-Type: application/json
{
  "error": "string"
}
404Family or member not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/families/admin/00000000-0000-4000-8000-000000000000/members/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Admin · Gifts

Showing 3 of 3 endpoints
GET/gifts/admin
Auth requiredgifts.admin.view

List gifts (admin)

Returns a paginated list of gifts scoped to the caller tenant/organization. Supports filtering by status (csv), sender, claimer, and free-text search (q) matching the gift invite code, the sender/claimer by email or name, and the gift amount/currency (e.g. "PLN10", "10 zł", or "EUR"). Requires features: gifts.admin.view

Parameters

NameInRequiredSchemaDescription
statusqueryYesany
senderUserIdqueryNoany
claimerUserIdqueryNoany
tenantIdqueryNoany
organizationIdqueryNoany
qqueryNoany
pagequeryNoany
pageSizequeryNoany
sortqueryNoany

Responses

200Gift list
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "senderUserId": "00000000-0000-4000-8000-000000000000",
      "senderWalletId": "00000000-0000-4000-8000-000000000000",
      "amountEuroCents": 1,
      "originalCurrency": "string",
      "originalAmountMinorUnits": 1,
      "status": "pending",
      "inviteCode": "string",
      "inviteCodeId": "00000000-0000-4000-8000-000000000000",
      "debitTransactionId": "00000000-0000-4000-8000-000000000000",
      "refundTransactionId": null,
      "claimTransactionId": null,
      "claimedByUserId": null,
      "claimedByConsumerId": null,
      "claimedAt": null,
      "cancelledAt": null,
      "expiredAt": null,
      "expiresAt": "string",
      "tenantId": null,
      "organizationId": null,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/gifts/admin?page=1&pageSize=50&sort=createdAt%3Adesc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gifts/admin/{id}
Auth requiredgifts.admin.view

Get gift detail (admin)

Returns a single gift scoped to the caller tenant/organization with linked wallet transactions, invite code summary, and minimal sender/claimer profiles. Requires features: gifts.admin.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Gift detail
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "senderUserId": "00000000-0000-4000-8000-000000000000",
  "senderWalletId": "00000000-0000-4000-8000-000000000000",
  "amountEuroCents": 1,
  "originalCurrency": "string",
  "originalAmountMinorUnits": 1,
  "status": "pending",
  "inviteCode": {
    "id": "00000000-0000-4000-8000-000000000000",
    "code": "string",
    "scope": "string",
    "createdAt": "string",
    "expiresAt": null,
    "revokedAt": null,
    "usedAt": null
  },
  "inviteCodeId": "00000000-0000-4000-8000-000000000000",
  "debitTransactionId": "00000000-0000-4000-8000-000000000000",
  "refundTransactionId": null,
  "claimTransactionId": null,
  "claimedByUserId": null,
  "claimedByConsumerId": null,
  "claimedAt": null,
  "cancelledAt": null,
  "expiredAt": null,
  "expiresAt": "string",
  "tenantId": null,
  "organizationId": null,
  "createdAt": "string",
  "updatedAt": "string",
  "transactions": {
    "created": null,
    "claimed": null,
    "cancelled": null
  },
  "sender": null,
  "claimer": null
}
400Invalid params
Content-Type: application/json
{
  "error": "string"
}
404Gift not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/gifts/admin/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gifts/admin/{id}/cancel
Auth requiredgifts.admin.cancel

Admin cancel a pending gift

Admin-initiated cancel of a pending gift. Same `pending`-only constraint as sender-cancel — it only skips the sender-ownership check and records admin attribution. Refunds the gift's `amountEuroCents` to the sender's standard wallet as a `gift_refund` credit batch, revokes the invite code, and records the admin user + optional reason in the action log. Shares the `gift-refund:<giftId>` idempotency key with sender-cancel and the expire-sweep worker so the refund is applied at most once. Sender-initiated cancel lives at `DELETE /api/gifts/me/gifts/[id]`. Requires features: gifts.admin.cancel

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{}

Responses

200Gift cancelled and refund issued
Content-Type: application/json
{
  "giftId": "00000000-0000-4000-8000-000000000000",
  "status": "cancelled",
  "refundTransactionId": "00000000-0000-4000-8000-000000000000",
  "amountEuroCents": 1,
  "originalCurrency": "string",
  "originalAmountMinorUnits": 1
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Gift not found
Content-Type: application/json
{
  "error": "string"
}
409Gift not in pending state
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/gifts/admin/00000000-0000-4000-8000-000000000000/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"

Meta

Showing 3 of 3 endpoints
GET/meta/admin/config
Auth required

Read app config (admin)

Requires roles: superadmin

Responses

200App config record
Content-Type: application/json
{
  "stripePublishableKey": "string",
  "minAppVersionIos": "string",
  "minAppVersionAndroid": "string",
  "iosAppLink": "string",
  "androidAppLink": "string",
  "updatedAt": "string"
}
403Forbidden
Content-Type: application/json
{
  "error": "string"
}
404Not initialized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/meta/admin/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/meta/admin/config
Auth required

Update app config (admin)

Requires roles: superadmin

Request body (application/json)

{
  "stripePublishableKey": "string",
  "minAppVersionIos": "string",
  "minAppVersionAndroid": "string",
  "iosAppLink": "https://example.com/resource",
  "androidAppLink": "https://example.com/resource"
}

Responses

200Updated app config
Content-Type: application/json
{
  "stripePublishableKey": "string",
  "minAppVersionIos": "string",
  "minAppVersionAndroid": "string",
  "iosAppLink": "string",
  "androidAppLink": "string",
  "updatedAt": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
403Forbidden
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://admin.getcovo.com/api/meta/admin/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"stripePublishableKey\": \"string\",
  \"minAppVersionIos\": \"string\",
  \"minAppVersionAndroid\": \"string\",
  \"iosAppLink\": \"https://example.com/resource\",
  \"androidAppLink\": \"https://example.com/resource\"
}"
GET/meta/config

Public bootstrap config for mobile app

Returns Stripe publishable key and minimum app versions. Unauthenticated; cached for 60 seconds.

Responses

200App bootstrap config
Content-Type: application/json
{
  "stripePublishableKey": "string",
  "minAppVersion": {
    "ios": "string",
    "android": "string"
  },
  "appLink": {
    "ios": "string",
    "android": "string"
  }
}

Example

curl -X GET "https://admin.getcovo.com/api/meta/config" \
  -H "Accept: application/json"

Payments Admin

Showing 3 of 3 endpoints
GET/payments/admin/invoices
Auth requiredpayments.admin.invoices.view

List invoices (admin)

Returns Stripe invoices scoped to the admin caller's tenant/organization, newest first. Supports optional `status`, `userId`, and `search` filters plus `limit`/`offset` pagination. The `search` parameter is tokenized by whitespace (up to 5 tokens); each token must appear in `invoice_number`, `stripe_invoice_id`, or anywhere in the `billing_snapshot` jsonb (user/billing/tax-rate values captured at invoice creation time). Requires features: payments.admin.invoices.view

Parameters

NameInRequiredSchemaDescription
statusqueryNoany
userIdqueryNoany
searchqueryNoany
limitqueryNoany
offsetqueryNoany

Responses

200Admin invoice list
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "stripeInvoiceId": "string",
      "status": "draft",
      "amount": {
        "amountInMinorUnits": 1,
        "currency": "string"
      },
      "invoiceNumber": null,
      "hostedInvoiceUrl": null,
      "invoicePdfUrl": null,
      "reverseCharge": true,
      "createdAt": "string",
      "updatedAt": "string",
      "userId": "00000000-0000-4000-8000-000000000000",
      "tenantId": null,
      "organizationId": null,
      "taxRateId": null,
      "taxPercentage": null,
      "taxInclusive": null,
      "billingSnapshot": null
    }
  ],
  "total": 1
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
500Failed to load invoices
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/admin/invoices?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/payments/admin/invoices/{id}
Auth requiredpayments.admin.invoices.view

Get a single invoice (admin)

Returns a single invoice by id, scoped to the admin caller's tenant/organization. Includes the point-in-time `billingSnapshot` captured at invoice creation. Requires features: payments.admin.invoices.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Invoice
Content-Type: application/json
{
  "invoice": {
    "id": "00000000-0000-4000-8000-000000000000",
    "stripeInvoiceId": "string",
    "status": "draft",
    "amount": {
      "amountInMinorUnits": 1,
      "currency": "string"
    },
    "invoiceNumber": null,
    "hostedInvoiceUrl": null,
    "invoicePdfUrl": null,
    "reverseCharge": true,
    "createdAt": "string",
    "updatedAt": "string",
    "userId": "00000000-0000-4000-8000-000000000000",
    "tenantId": null,
    "organizationId": null,
    "taxRateId": null,
    "taxPercentage": null,
    "taxInclusive": null,
    "billingSnapshot": null
  }
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Invoice not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load invoice
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/admin/invoices/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/payments/admin/invoices/{id}/payments
Auth requiredpayments.admin.invoices.view

List payments linked to an invoice (admin)

Returns all payments where `invoice_id` matches the given invoice id, scoped to the admin caller's tenant/organization. Capped at 50 results - in practice an invoice has at most a couple of linked payments (the initial PaymentIntent plus any retry). Requires features: payments.admin.invoices.view

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Linked payments
Content-Type: application/json
{
  "payments": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "walletId": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "invoiceId": null,
      "status": "pending",
      "paymentType": "top_up",
      "amountEuroCents": null,
      "amountRefundedEuroCents": 1,
      "stripeFeeEurCents": 1,
      "originalCurrency": "string",
      "originalAmountMinorUnits": 1,
      "stripePaymentIntentId": "string",
      "description": "string",
      "failureReason": null,
      "refundedAt": null,
      "refundReason": null,
      "clientIp": null,
      "clientUserAgent": null,
      "clientDeviceId": null,
      "clientAppVersion": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Invoice not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load linked payments
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/admin/invoices/00000000-0000-4000-8000-000000000000/payments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Payments Internal

Showing 3 of 3 endpoints
GET/payments/internal/test/stripe-stub/customers/{id}

Return the in-memory Stripe stub customer default

Only available when OM_TEST_MODE=1. Returns 404 otherwise.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Customer default
Content-Type: application/json
{
  "customerId": "string",
  "defaultPaymentMethodId": null
}
404Endpoint disabled (OM_TEST_MODE not set)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/payments/internal/test/stripe-stub/customers/string" \
  -H "Accept: application/json"
POST/payments/internal/test/stripe-stub/payment-methods

Seed a payment method into the in-memory Stripe stub

Only available when OM_TEST_MODE=1. Returns 404 otherwise. Used by Playwright integration tests to set up customer-attached payment methods before exercising auto-refill or admin listing flows.

Request body (application/json)

{
  "customer": "string"
}

Responses

200Seeded
Content-Type: application/json
{
  "stripePaymentMethodId": "string"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Endpoint disabled (OM_TEST_MODE not set)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/payments/internal/test/stripe-stub/payment-methods" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"customer\": \"string\"
}"
DELETE/payments/internal/test/stripe-stub/payment-methods/{id}

Remove a payment method from the in-memory Stripe stub

Only available when OM_TEST_MODE=1. Returns 404 otherwise.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Deleted
Content-Type: application/json
{
  "ok": true
}
404Endpoint disabled (OM_TEST_MODE not set)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/payments/internal/test/stripe-stub/payment-methods/string" \
  -H "Accept: application/json"

Query Index

Showing 3 of 3 endpoints
POST/query_index/purge
Auth requiredquery_index.purge

Purge query index records

Queues a purge job to remove indexed records for an entity type within the active scope. Requires features: query_index.purge

Request body (application/json)

{
  "entityType": "string"
}

Responses

200Purge job accepted.
Content-Type: application/json
{
  "ok": true
}
400Missing entity type
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/query_index/purge" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\"
}"
POST/query_index/reindex
Auth requiredquery_index.reindex

Trigger query index rebuild

Queues a reindex job for the specified entity type within the current tenant scope. Requires features: query_index.reindex

Request body (application/json)

{
  "entityType": "string"
}

Responses

200Reindex job accepted.
Content-Type: application/json
{
  "ok": true
}
400Missing entity type
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/query_index/reindex" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\"
}"
GET/query_index/status
Auth requiredquery_index.status.view

Inspect query index coverage

Returns entity counts comparing base tables with the query index along with the latest job status. Requires features: query_index.status.view

Responses

200Current query index status.
Content-Type: application/json
{
  "items": [
    {
      "entityId": "string",
      "label": "string",
      "baseCount": null,
      "indexCount": null,
      "vectorCount": null,
      "ok": true,
      "job": {
        "status": "idle",
        "startedAt": null,
        "finishedAt": null,
        "heartbeatAt": null,
        "processedCount": null,
        "totalCount": null,
        "scope": null
      }
    }
  ],
  "errors": [
    {
      "id": "string",
      "source": "string",
      "handler": "string",
      "entityType": null,
      "recordId": null,
      "tenantId": null,
      "organizationId": null,
      "message": "string",
      "stack": null,
      "payload": null,
      "occurredAt": "string"
    }
  ],
  "logs": [
    {
      "id": "string",
      "source": "string",
      "handler": "string",
      "level": "info",
      "entityType": null,
      "recordId": null,
      "tenantId": null,
      "organizationId": null,
      "message": "string",
      "details": null,
      "occurredAt": "string"
    }
  ]
}
400Tenant or organization context required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/query_index/status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

User Notifications Admin

Showing 8 of 8 endpoints
GET/user_notifications/admin/deliveries
Auth requireduser_notifications.manage

List push notification deliveries (admin)

Returns paginated delivery records with joined notification type, notification group (the prefix of `type` before the first dot), device platform and token suffix. Filter by status, category, notification `type` (exact), `group` (prefix match on type), userId, silent, and creation date range, or free-text search on the recipient by email or name. Requires features: user_notifications.manage

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
statusqueryNoany
categoryqueryNoany
typequeryNoany
groupqueryNoany
userIdqueryNoany
searchqueryNoany
silentqueryNoany
createdFromqueryNoany
createdToqueryNoany

Responses

200Paginated list of push deliveries
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "notificationId": "00000000-0000-4000-8000-000000000000",
      "notificationType": null,
      "notificationGroup": null,
      "tokenId": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "category": null,
      "status": "pending",
      "error": null,
      "attempts": 1,
      "silent": true,
      "sentAt": null,
      "createdAt": "string",
      "updatedAt": "string",
      "devicePlatform": null,
      "deviceTokenSuffix": null,
      "deviceIsActive": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/user_notifications/admin/deliveries?page=1&pageSize=25&sortField=createdAt&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/user_notifications/admin/deliveries/{id}
Auth requireduser_notifications.manage

Get a push delivery with joined notification and sibling deliveries

Returns the delivery, its upstream Notification, NotificationType metadata and all deliveries that share the same notification (one per device). Requires features: user_notifications.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Push delivery detail payload
Content-Type: application/json
{
  "delivery": {
    "id": "00000000-0000-4000-8000-000000000000",
    "tokenId": "00000000-0000-4000-8000-000000000000",
    "devicePlatform": null,
    "deviceTokenSuffix": null,
    "deviceIsActive": null,
    "status": "pending",
    "error": null,
    "attempts": 1,
    "silent": true,
    "sentAt": null,
    "createdAt": "string",
    "updatedAt": "string",
    "notificationId": "00000000-0000-4000-8000-000000000000",
    "userId": "00000000-0000-4000-8000-000000000000",
    "category": null
  },
  "notification": {
    "id": "00000000-0000-4000-8000-000000000000",
    "type": "string",
    "title": "string",
    "body": null,
    "titleKey": null,
    "bodyKey": null,
    "titleVariables": null,
    "bodyVariables": null,
    "severity": "string",
    "recipientUserId": "00000000-0000-4000-8000-000000000000",
    "sourceModule": null,
    "sourceEntityType": null,
    "sourceEntityId": null,
    "createdAt": "string"
  },
  "notificationType": null,
  "siblingDeliveries": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "tokenId": "00000000-0000-4000-8000-000000000000",
      "devicePlatform": null,
      "deviceTokenSuffix": null,
      "deviceIsActive": null,
      "status": "pending",
      "error": null,
      "attempts": 1,
      "silent": true,
      "sentAt": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ]
}
400Invalid ID
Content-Type: application/json
{
  "error": "string"
}
404Delivery not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/user_notifications/admin/deliveries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/user_notifications/admin/notification-preferences/{userId}
Auth requireduser_notifications.manage_preferences

Get a user's notification preferences (admin)

Returns one preference row per registered notification type for the given user. Target user must belong to the caller tenant. Requires features: user_notifications.manage_preferences

Parameters

NameInRequiredSchemaDescription
userIdpathYesany

Responses

200Preferences
Content-Type: application/json
{
  "preferences": [
    {
      "type": "string",
      "category": "string",
      "group": "string",
      "nonOptOut": true,
      "pushEnabled": true,
      "emailEnabled": true
    }
  ]
}
400Invalid ID
Content-Type: application/json
{
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/user_notifications/admin/notification-preferences/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/user_notifications/admin/notification-preferences/{userId}
Auth requireduser_notifications.manage_preferences

Update a user's notification preferences (admin)

Batch update preferences for the given user. Routed through CommandBus for action logging. Non-opt-out types are server-enforced as enabled regardless of submitted values. Requires features: user_notifications.manage_preferences

Parameters

NameInRequiredSchemaDescription
userIdpathYesany

Request body (application/json)

{
  "preferences": [
    {
      "type": "string",
      "pushEnabled": true,
      "emailEnabled": true
    }
  ]
}

Responses

200Updated preferences
Content-Type: application/json
{
  "preferences": [
    {
      "type": "string",
      "category": "string",
      "group": "string",
      "nonOptOut": true,
      "pushEnabled": true,
      "emailEnabled": true
    }
  ]
}
400Invalid input
Content-Type: application/json
{
  "error": "string",
  "issues": []
}
404User not found
Content-Type: application/json
{
  "error": "string"
}
500Update failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://admin.getcovo.com/api/user_notifications/admin/notification-preferences/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"preferences\": [
    {
      \"type\": \"string\",
      \"pushEnabled\": true,
      \"emailEnabled\": true
    }
  ]
}"
GET/user_notifications/admin/push-devices
Auth requireduser_notifications.manage

List registered push notification devices (admin)

Returns paginated device records with joined user email and display name. Filter by userId, platform, isActive, pushPermitted, and updated date range, or free-text search by user email/name or device id. Requires features: user_notifications.manage

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
sortFieldqueryNoany
sortDirqueryNoany
userIdqueryNoany
searchqueryNoany
platformqueryNoany
isActivequeryNoany
pushPermittedqueryNoany
updatedFromqueryNoany
updatedToqueryNoany

Responses

200Paginated list of push devices
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "deviceId": "string",
      "tokenSuffix": "string",
      "platform": "ios",
      "pushPermitted": true,
      "isActive": true,
      "createdAt": "string",
      "updatedAt": "string",
      "userEmail": null,
      "userName": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://admin.getcovo.com/api/user_notifications/admin/push-devices?page=1&pageSize=25&sortField=updatedAt&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/user_notifications/admin/push-devices/{id}
Auth requireduser_notifications.manage

Get a push notification device with recent delivery history

Returns the device record (including full token), joined user identity (email + display name), and the most recent delivery attempts targeting this token (up to historyLimit). Requires features: user_notifications.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Push device detail payload
Content-Type: application/json
{
  "device": {
    "id": "00000000-0000-4000-8000-000000000000",
    "tenantId": "00000000-0000-4000-8000-000000000000",
    "userId": "00000000-0000-4000-8000-000000000000",
    "deviceId": "string",
    "token": "string",
    "tokenSuffix": "string",
    "platform": "ios",
    "pushPermitted": true,
    "isActive": true,
    "createdAt": "string",
    "updatedAt": "string",
    "userEmail": null,
    "userName": null
  },
  "recentDeliveries": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "notificationId": "00000000-0000-4000-8000-000000000000",
      "notificationType": null,
      "notificationGroup": null,
      "status": "pending",
      "error": null,
      "attempts": 1,
      "category": null,
      "sentAt": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "historyLimit": 1
}
400Invalid ID
Content-Type: application/json
{
  "error": "string"
}
404Device not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/user_notifications/admin/push-devices/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/user_notifications/admin/push-devices/deactivate
Auth requireduser_notifications.manage

Deactivate a push notification device (admin)

Sets `is_active = false` on a registered push device. Undoable via the action log. Requires features: user_notifications.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Device deactivated (or was already inactive)
Content-Type: application/json
{
  "alreadyInactive": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string",
  "issues": []
}
404Device not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/user_notifications/admin/push-devices/deactivate" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
POST/user_notifications/admin/send-custom
Auth requireduser_notifications.send_custom

Send a custom push notification (admin)

Sends a one-off push notification to a chosen user. `pushDeviceIds` is the list of push notification token row ids to target; clients pass a single id to target one device or all of the user's ids to fan out. The notification is also persisted to the user's in-app feed. Requires features: user_notifications.send_custom

Request body (application/json)

{
  "userId": "00000000-0000-4000-8000-000000000000",
  "pushDeviceIds": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "title": "string",
  "body": "string",
  "silent": false
}

Responses

200Notification persisted and dispatched
Content-Type: application/json
{
  "notificationId": "00000000-0000-4000-8000-000000000000",
  "deliveries": [
    {
      "deviceId": "string",
      "pushDeviceId": "00000000-0000-4000-8000-000000000000",
      "status": "sent",
      "error": null
    }
  ],
  "sentCount": 1,
  "failedCount": 1,
  "pendingCount": 1
}
400Invalid payload
Content-Type: application/json
{
  "error": "string",
  "issues": []
}
404Device not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/user_notifications/admin/send-custom" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"userId\": \"00000000-0000-4000-8000-000000000000\",
  \"pushDeviceIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ],
  \"title\": \"string\",
  \"body\": \"string\",
  \"silent\": false
}"

Wallet Admin

Showing 9 of 9 endpoints
GET/wallet/admin/wallets
Auth requiredwallet.admin.list

List all wallets

Returns paginated list of all wallets with optional type filter. The search query matches the wallet owner by partial email (via the search token index) or by first/last name. Each wallet also includes an optional displayBalance in the owner's display currency when that currency is set and differs from EUR. Requires features: wallet.admin.list

Parameters

NameInRequiredSchemaDescription
idqueryNoany
userIdqueryNoany
searchqueryNoany
typequeryNoany
limitqueryNoany
offsetqueryNoany

Responses

200Wallet list
Content-Type: application/json
{
  "wallets": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "userEmail": "string",
      "userName": null,
      "type": "standard",
      "balance": {
        "amountInMinorUnits": 1,
        "currency": "string"
      },
      "lastTransactionAt": null
    }
  ],
  "total": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/admin/wallets?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/wallet/admin/wallets
Auth requiredwallet.admin.create

Create wallets for user

Creates standard and bonus wallets for a user. Idempotent — returns existing wallets if already created. Requires features: wallet.admin.create

Request body (application/json)

{
  "userId": "00000000-0000-4000-8000-000000000000"
}

Responses

201Wallets created
Content-Type: application/json
{
  "standardId": "00000000-0000-4000-8000-000000000000",
  "bonusId": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/wallet/admin/wallets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"userId\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/wallet/admin/wallets/{id}/payment-methods
Auth requiredwallet.admin.list

List a wallet owner's saved Stripe payment methods

Reads the wallet's owner Stripe customer and lists the customer's card payment methods that are reusable off-session (allow_redisplay='always'). Marks the one set as invoice_settings.default_payment_method as the default. Returns an empty list when the user has no Stripe customer yet. Requires features: wallet.admin.list

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Payment methods
Content-Type: application/json
{
  "methods": [
    {
      "stripePaymentMethodId": "string",
      "type": "string",
      "cardBrand": null,
      "cardLast4": null,
      "cardExpMonth": null,
      "cardExpYear": null,
      "isDefault": true
    }
  ]
}
400Invalid path parameter (non-UUID wallet id)
Content-Type: application/json
{
  "error": "string"
}
404Wallet not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/admin/wallets/00000000-0000-4000-8000-000000000000/payment-methods" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/admin/wallets/{id}/payments
Auth requiredwallet.admin.list

List wallet payments

Returns paginated list of Stripe-backed payments for a specific wallet. Requires features: wallet.admin.list

Parameters

NameInRequiredSchemaDescription
idpathYesany
statusqueryNoany
paymentTypequeryNoany
limitqueryNoany
offsetqueryNoany

Responses

200Payment list
Content-Type: application/json
{
  "payments": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "walletId": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "invoiceId": null,
      "status": "pending",
      "paymentType": "top_up",
      "amountEuroCents": null,
      "amountRefundedEuroCents": 1,
      "stripeFeeEurCents": 1,
      "originalCurrency": "string",
      "originalAmountMinorUnits": 1,
      "stripePaymentIntentId": "string",
      "description": "string",
      "failureReason": null,
      "refundedAt": null,
      "refundReason": null,
      "clientIp": null,
      "clientUserAgent": null,
      "clientDeviceId": null,
      "clientAppVersion": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
404Wallet not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/admin/wallets/00000000-0000-4000-8000-000000000000/payments?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/admin/wallets/{id}/payments/{paymentId}
Auth requiredwallet.admin.list

Get single wallet payment

Returns a single Stripe-backed payment by id, scoped to the given wallet. Requires features: wallet.admin.list

Parameters

NameInRequiredSchemaDescription
idpathYesany
paymentIdpathYesany

Responses

200Payment
Content-Type: application/json
{
  "payment": {
    "id": "00000000-0000-4000-8000-000000000000",
    "walletId": "00000000-0000-4000-8000-000000000000",
    "userId": "00000000-0000-4000-8000-000000000000",
    "invoiceId": null,
    "status": "pending",
    "paymentType": "top_up",
    "amountEuroCents": null,
    "amountRefundedEuroCents": 1,
    "stripeFeeEurCents": 1,
    "originalCurrency": "string",
    "originalAmountMinorUnits": 1,
    "stripePaymentIntentId": "string",
    "description": "string",
    "failureReason": null,
    "refundedAt": null,
    "refundReason": null,
    "clientIp": null,
    "clientUserAgent": null,
    "clientDeviceId": null,
    "clientAppVersion": null,
    "createdAt": "string",
    "updatedAt": "string"
  }
}
404Wallet or payment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/admin/wallets/00000000-0000-4000-8000-000000000000/payments/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/admin/wallets/{id}/payments/{paymentId}/stripe-calls
Auth requiredwallet.admin.list

List Stripe API calls related to a single payment

Returns paginated Stripe API calls (outbound + inbound webhooks + admin actions) for a specific payment. Correlates via direct payment_id, or via stripe_payment_intent_id for webhooks logged before the payment record was linked. Requires features: wallet.admin.list

Parameters

NameInRequiredSchemaDescription
idpathYesany
paymentIdpathYesany
pagequeryNoany
pageSizequeryNoany
directionqueryNoany
handlingStatusqueryNoany

Responses

200Stripe API calls
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "direction": "outbound",
      "handlingStatus": null,
      "method": "string",
      "endpoint": "string",
      "eventType": null,
      "statusCode": null,
      "durationMs": null,
      "idempotencyKey": null,
      "externalEventId": null,
      "errorMessage": null,
      "requestId": null,
      "requestHeaders": null,
      "requestBody": null,
      "responseHeaders": null,
      "responseBody": null,
      "paymentId": null,
      "walletId": null,
      "userId": null,
      "stripePaymentIntentId": null,
      "stripeChargeId": null,
      "stripeCustomerId": null,
      "stripeSetupIntentId": null,
      "stripeRefundId": null,
      "trigger": null,
      "triggers": null,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
404Wallet or payment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/admin/wallets/00000000-0000-4000-8000-000000000000/payments/00000000-0000-4000-8000-000000000000/stripe-calls?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/admin/wallets/{id}/stripe-calls
Auth requiredwallet.admin.list

List Stripe API calls related to a wallet

Returns paginated Stripe API calls (outbound + inbound webhooks + admin actions) correlated to a specific wallet via direct wallet_id or via any payment owned by the wallet. Requires features: wallet.admin.list

Parameters

NameInRequiredSchemaDescription
idpathYesany
pagequeryNoany
pageSizequeryNoany
directionqueryNoany
handlingStatusqueryNoany

Responses

200Stripe API calls
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "direction": "outbound",
      "handlingStatus": null,
      "method": "string",
      "endpoint": "string",
      "eventType": null,
      "statusCode": null,
      "durationMs": null,
      "idempotencyKey": null,
      "externalEventId": null,
      "errorMessage": null,
      "requestId": null,
      "requestHeaders": null,
      "requestBody": null,
      "responseHeaders": null,
      "responseBody": null,
      "paymentId": null,
      "walletId": null,
      "userId": null,
      "stripePaymentIntentId": null,
      "stripeChargeId": null,
      "stripeCustomerId": null,
      "stripeSetupIntentId": null,
      "stripeRefundId": null,
      "trigger": null,
      "triggers": null,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
404Wallet not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/admin/wallets/00000000-0000-4000-8000-000000000000/stripe-calls?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/admin/wallets/{id}/transactions
Auth requiredwallet.admin.list

List wallet transactions

Returns paginated list of transactions for a specific wallet. Requires features: wallet.admin.list

Parameters

NameInRequiredSchemaDescription
idpathYesany
typequeryNoany
limitqueryNoany
offsetqueryNoany

Responses

200Transaction list
Content-Type: application/json
{
  "transactions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "type": "credit",
      "amount": {
        "amountInMinorUnits": 1,
        "currency": "string"
      },
      "description": "string",
      "referenceType": "top_up",
      "referenceId": null,
      "createdAt": "string"
    }
  ],
  "total": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
404Wallet not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/admin/wallets/00000000-0000-4000-8000-000000000000/transactions?limit=20&offset=0" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/wallet/admin/wallets/{id}/transactions
Auth requiredwallet.admin.adjust

Create manual wallet adjustment

Credits or debits a wallet manually for support/adjustment purposes. Requires features: wallet.admin.adjust

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "type": "credit",
  "amountEuroCents": 1,
  "reason": "string"
}

Responses

200Transaction created
Content-Type: application/json
{
  "transactionId": "00000000-0000-4000-8000-000000000000",
  "newBalance": {
    "amountInMinorUnits": 1,
    "currency": "string"
  }
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Wallet not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/wallet/admin/wallets/00000000-0000-4000-8000-000000000000/transactions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"type\": \"credit\",
  \"amountEuroCents\": 1,
  \"reason\": \"string\"
}"

Wallet Dashboards

Showing 2 of 2 endpoints
GET/wallet/dashboards/recent-activity
Auth requiredanalytics.viewwallet.admin.list

Recent activity

Returns the latest mixed-stream of wallet top-ups, spend, refunds, and eSIM activations scoped to the caller's tenant/organization. User labels are first-name + last-initial for privacy. Requires features: analytics.view, wallet.admin.list

Parameters

NameInRequiredSchemaDescription
limitqueryNoany

Responses

200Recent activity items
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "kind": "top_up",
      "occurredAt": "string",
      "userLabel": "string",
      "amountEuroCents": null
    }
  ],
  "fetchedAt": "string"
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}
500Failed to load recent activity
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/dashboards/recent-activity?limit=10" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/wallet/dashboards/total-balance
Auth requiredanalytics.viewwallet.admin.list

Total wallet balance

Returns the sum of all wallet balances (in EUR cents) scoped to the caller's tenant/organization, plus the change versus the start of the requested date-range preset (default last_30_days). Requires features: analytics.view, wallet.admin.list

Parameters

NameInRequiredSchemaDescription
presetqueryNoany

Responses

200Total balance with monthly comparison
Content-Type: application/json
{
  "value": 1,
  "comparison": null,
  "fetchedAt": "string"
}
500Failed to load total balance
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/wallet/dashboards/total-balance" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Workflows

Showing 20 of 23 endpoints
GET/workflows/definitions

List workflow definitions

Get a list of workflow definitions with optional filters. Supports pagination and search.

Parameters

NameInRequiredSchemaDescription
workflowIdqueryYesany
enabledqueryNoany
searchqueryNoany
limitqueryNoany
offsetqueryNoany

Responses

200List of workflow definitions with pagination
Content-Type: application/json
{
  "data": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "workflowId": "checkout-flow",
      "workflowName": "Checkout Flow",
      "description": "Complete checkout workflow for processing orders",
      "version": 1,
      "definition": {
        "steps": [
          {
            "stepId": "start",
            "stepName": "Start",
            "stepType": "START"
          },
          {
            "stepId": "validate-cart",
            "stepName": "Validate Cart",
            "stepType": "AUTOMATED"
          },
          {
            "stepId": "end",
            "stepName": "End",
            "stepType": "END"
          }
        ],
        "transitions": [
          {
            "transitionId": "start-to-validate",
            "fromStepId": "start",
            "toStepId": "validate-cart",
            "trigger": "auto"
          },
          {
            "transitionId": "validate-to-end",
            "fromStepId": "validate-cart",
            "toStepId": "end",
            "trigger": "auto"
          }
        ]
      },
      "enabled": true,
      "tenantId": "123e4567-e89b-12d3-a456-426614174001",
      "organizationId": "123e4567-e89b-12d3-a456-426614174002",
      "createdAt": "2025-12-08T10:00:00.000Z",
      "updatedAt": "2025-12-08T10:00:00.000Z"
    }
  ],
  "pagination": {
    "total": 1,
    "limit": 50,
    "offset": 0,
    "hasMore": false
  }
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/definitions?workflowId=string&limit=50&offset=0" \
  -H "Accept: application/json"
POST/workflows/definitions

Create workflow definition

Create a new workflow definition. The definition must include at least START and END steps with at least one transition connecting them.

Request body (application/json)

{
  "workflowId": "checkout-flow",
  "workflowName": "Checkout Flow",
  "description": "Complete checkout workflow for processing orders",
  "version": 1,
  "definition": {
    "steps": [
      {
        "stepId": "start",
        "stepName": "Start",
        "stepType": "START"
      },
      {
        "stepId": "validate-cart",
        "stepName": "Validate Cart",
        "stepType": "AUTOMATED",
        "description": "Validate cart items and check inventory"
      },
      {
        "stepId": "payment",
        "stepName": "Process Payment",
        "stepType": "AUTOMATED",
        "description": "Charge payment method",
        "retryPolicy": {
          "maxAttempts": 3,
          "backoffMs": 1000
        }
      },
      {
        "stepId": "end",
        "stepName": "End",
        "stepType": "END"
      }
    ],
    "transitions": [
      {
        "transitionId": "start-to-validate",
        "fromStepId": "start",
        "toStepId": "validate-cart",
        "trigger": "auto"
      },
      {
        "transitionId": "validate-to-payment",
        "fromStepId": "validate-cart",
        "toStepId": "payment",
        "trigger": "auto"
      },
      {
        "transitionId": "payment-to-end",
        "fromStepId": "payment",
        "toStepId": "end",
        "trigger": "auto",
        "activities": [
          {
            "activityName": "Send Order Confirmation",
            "activityType": "SEND_EMAIL",
            "config": {
              "to": "{{context.customerEmail}}",
              "subject": "Order Confirmation #{{context.orderId}}",
              "template": "order_confirmation"
            }
          }
        ]
      }
    ]
  },
  "enabled": true
}

Responses

201Workflow definition created successfully
Content-Type: application/json
{
  "data": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "workflowId": "checkout-flow",
    "workflowName": "Checkout Flow",
    "description": "Complete checkout workflow for processing orders",
    "version": 1,
    "definition": {
      "steps": [
        {
          "stepId": "start",
          "stepName": "Start",
          "stepType": "START"
        },
        {
          "stepId": "validate-cart",
          "stepName": "Validate Cart",
          "stepType": "AUTOMATED"
        },
        {
          "stepId": "payment",
          "stepName": "Process Payment",
          "stepType": "AUTOMATED"
        },
        {
          "stepId": "end",
          "stepName": "End",
          "stepType": "END"
        }
      ],
      "transitions": [
        {
          "transitionId": "start-to-validate",
          "fromStepId": "start",
          "toStepId": "validate-cart",
          "trigger": "auto"
        },
        {
          "transitionId": "validate-to-payment",
          "fromStepId": "validate-cart",
          "toStepId": "payment",
          "trigger": "auto"
        },
        {
          "transitionId": "payment-to-end",
          "fromStepId": "payment",
          "toStepId": "end",
          "trigger": "auto"
        }
      ]
    },
    "enabled": true,
    "tenantId": "123e4567-e89b-12d3-a456-426614174001",
    "organizationId": "123e4567-e89b-12d3-a456-426614174002",
    "createdAt": "2025-12-08T10:00:00.000Z",
    "updatedAt": "2025-12-08T10:00:00.000Z"
  },
  "message": "Workflow definition created successfully"
}
400Validation error - invalid workflow structure
Content-Type: application/json
{
  "error": "Validation failed",
  "details": [
    {
      "code": "invalid_type",
      "message": "Workflow must have at least START and END steps",
      "path": [
        "definition",
        "steps"
      ]
    }
  ]
}
409Conflict - workflow with same ID and version already exists
Content-Type: application/json
{
  "error": "Workflow definition with ID \"checkout-flow\" and version 1 already exists"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/definitions" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"workflowId\": \"string\",
  \"workflowName\": \"string\",
  \"description\": null,
  \"version\": 1,
  \"definition\": {
    \"steps\": [
      {
        \"stepId\": \"string\",
        \"stepName\": \"string\",
        \"stepType\": \"START\"
      }
    ],
    \"transitions\": [
      {
        \"transitionId\": \"string\",
        \"fromStepId\": \"string\",
        \"toStepId\": \"string\",
        \"trigger\": \"auto\",
        \"continueOnActivityFailure\": false,
        \"priority\": 0
      }
    ]
  },
  \"metadata\": null,
  \"enabled\": true
}"
GET/workflows/definitions/{id}

Get workflow definition

Get a single workflow definition by ID. Returns the complete workflow structure including steps and transitions (with embedded activities).

Parameters

NameInRequiredSchemaDescription
idpathYesanyUUID for DB definitions, or "code:<workflowId>" for code-based definitions

Responses

200Workflow definition found
Content-Type: application/json
{
  "data": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "workflowId": "checkout-flow",
    "workflowName": "Checkout Flow",
    "description": "Complete checkout workflow for processing orders",
    "version": 1,
    "definition": {
      "steps": [
        {
          "stepId": "start",
          "stepName": "Start",
          "stepType": "START"
        },
        {
          "stepId": "validate-cart",
          "stepName": "Validate Cart",
          "stepType": "AUTOMATED",
          "description": "Validate cart items and check inventory"
        },
        {
          "stepId": "payment",
          "stepName": "Process Payment",
          "stepType": "AUTOMATED",
          "description": "Charge payment method",
          "retryPolicy": {
            "maxAttempts": 3,
            "backoffMs": 1000
          }
        },
        {
          "stepId": "end",
          "stepName": "End",
          "stepType": "END"
        }
      ],
      "transitions": [
        {
          "transitionId": "start-to-validate",
          "fromStepId": "start",
          "toStepId": "validate-cart",
          "trigger": "auto"
        },
        {
          "transitionId": "validate-to-payment",
          "fromStepId": "validate-cart",
          "toStepId": "payment",
          "trigger": "auto"
        },
        {
          "transitionId": "payment-to-end",
          "fromStepId": "payment",
          "toStepId": "end",
          "trigger": "auto",
          "activities": [
            {
              "activityName": "Send Order Confirmation",
              "activityType": "SEND_EMAIL",
              "config": {
                "to": "{{context.customerEmail}}",
                "subject": "Order Confirmation #{{context.orderId}}",
                "template": "order_confirmation"
              }
            }
          ]
        }
      ]
    },
    "enabled": true,
    "tenantId": "123e4567-e89b-12d3-a456-426614174001",
    "organizationId": "123e4567-e89b-12d3-a456-426614174002",
    "createdAt": "2025-12-08T10:00:00.000Z",
    "updatedAt": "2025-12-08T10:00:00.000Z"
  }
}
404Workflow definition not found
Content-Type: application/json
{
  "error": "Workflow definition not found"
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/definitions/string" \
  -H "Accept: application/json"
PUT/workflows/definitions/{id}

Update workflow definition

Update an existing workflow definition. Supports partial updates - only provided fields will be updated.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "definition": {
    "steps": [
      {
        "stepId": "start",
        "stepName": "Start",
        "stepType": "START"
      },
      {
        "stepId": "validate-cart",
        "stepName": "Validate Cart",
        "stepType": "AUTOMATED"
      },
      {
        "stepId": "payment",
        "stepName": "Process Payment",
        "stepType": "AUTOMATED"
      },
      {
        "stepId": "confirmation",
        "stepName": "Order Confirmation",
        "stepType": "AUTOMATED"
      },
      {
        "stepId": "end",
        "stepName": "End",
        "stepType": "END"
      }
    ],
    "transitions": [
      {
        "transitionId": "start-to-validate",
        "fromStepId": "start",
        "toStepId": "validate-cart",
        "trigger": "auto"
      },
      {
        "transitionId": "validate-to-payment",
        "fromStepId": "validate-cart",
        "toStepId": "payment",
        "trigger": "auto"
      },
      {
        "transitionId": "payment-to-confirmation",
        "fromStepId": "payment",
        "toStepId": "confirmation",
        "trigger": "auto"
      },
      {
        "transitionId": "confirmation-to-end",
        "fromStepId": "confirmation",
        "toStepId": "end",
        "trigger": "auto"
      }
    ]
  },
  "enabled": true
}

Responses

200Workflow definition updated successfully
Content-Type: application/json
{
  "data": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "workflowId": "checkout-flow",
    "workflowName": "Checkout Flow",
    "description": "Complete checkout workflow for processing orders",
    "version": 1,
    "definition": {
      "steps": [
        {
          "stepId": "start",
          "stepName": "Start",
          "stepType": "START"
        },
        {
          "stepId": "validate-cart",
          "stepName": "Validate Cart",
          "stepType": "AUTOMATED"
        },
        {
          "stepId": "payment",
          "stepName": "Process Payment",
          "stepType": "AUTOMATED"
        },
        {
          "stepId": "confirmation",
          "stepName": "Order Confirmation",
          "stepType": "AUTOMATED"
        },
        {
          "stepId": "end",
          "stepName": "End",
          "stepType": "END"
        }
      ],
      "transitions": [
        {
          "transitionId": "start-to-validate",
          "fromStepId": "start",
          "toStepId": "validate-cart",
          "trigger": "auto"
        },
        {
          "transitionId": "validate-to-payment",
          "fromStepId": "validate-cart",
          "toStepId": "payment",
          "trigger": "auto"
        },
        {
          "transitionId": "payment-to-confirmation",
          "fromStepId": "payment",
          "toStepId": "confirmation",
          "trigger": "auto"
        },
        {
          "transitionId": "confirmation-to-end",
          "fromStepId": "confirmation",
          "toStepId": "end",
          "trigger": "auto"
        }
      ]
    },
    "enabled": true,
    "tenantId": "123e4567-e89b-12d3-a456-426614174001",
    "organizationId": "123e4567-e89b-12d3-a456-426614174002",
    "createdAt": "2025-12-08T10:00:00.000Z",
    "updatedAt": "2025-12-08T11:30:00.000Z"
  },
  "message": "Workflow definition updated successfully"
}
400Validation error
Content-Type: application/json
{
  "error": "Validation failed",
  "details": [
    {
      "code": "invalid_type",
      "message": "Expected object, received string",
      "path": [
        "definition"
      ]
    }
  ]
}
404Workflow definition not found
Content-Type: application/json
{
  "error": "Workflow definition not found"
}

Example

curl -X PUT "https://admin.getcovo.com/api/workflows/definitions/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"description\": null,
  \"metadata\": null,
  \"effectiveFrom\": null,
  \"effectiveTo\": null
}"
DELETE/workflows/definitions/{id}

Delete workflow definition

Soft delete a workflow definition. Cannot be deleted if there are active workflow instances (RUNNING or WAITING status) using this definition.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Workflow definition deleted successfully
Content-Type: application/json
{
  "message": "Workflow definition deleted successfully"
}
404Workflow definition not found
Content-Type: application/json
{
  "error": "Workflow definition not found"
}
409Cannot delete - active workflow instances exist
Content-Type: application/json
{
  "error": "Cannot delete workflow definition with 3 active instance(s)"
}

Example

curl -X DELETE "https://admin.getcovo.com/api/workflows/definitions/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
POST/workflows/definitions/{id}/customize

Customize code-based workflow definition

Creates a DB override for a code-based workflow definition, seeded from the current code registry values. The id param must be of the form "code:<workflowId>".

Parameters

NameInRequiredSchemaDescription
idpathYesanyMust be of the form "code:<workflowId>"

Responses

200Workflow definition customized successfully
Content-Type: application/json
{
  "data": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "workflowId": "workflows.simple-approval",
    "workflowName": "Simple Approval Workflow",
    "source": "code_override"
  },
  "message": "Workflow definition customized successfully"
}
400Not a code-based id
Content-Type: application/json
{
  "error": "Customize is only supported for code-based workflow definitions"
}
404Code workflow not found
Content-Type: application/json
{
  "error": "Workflow definition not found"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/definitions/string/customize" \
  -H "Accept: application/json"
POST/workflows/definitions/{id}/reset-to-code

Reset workflow definition to code version

Deletes the DB override for a code-based workflow definition, reverting it to the original code registry version. Cannot be reset if there are active instances.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Workflow definition reset to code version
Content-Type: application/json
{
  "data": {
    "id": "code:checkout-flow",
    "workflowId": "checkout-flow",
    "workflowName": "Checkout Flow",
    "description": "Code-defined checkout workflow",
    "version": 1,
    "source": "code",
    "isCodeBased": true
  },
  "message": "Workflow definition reset to code version"
}
400Definition is not a code-based override
Content-Type: application/json
{
  "error": "This workflow definition is not a code-based override and cannot be reset"
}
404Workflow definition not found
Content-Type: application/json
{
  "error": "Workflow definition not found"
}
409Cannot reset - active workflow instances exist
Content-Type: application/json
{
  "error": "Cannot reset workflow definition with 3 active instance(s)"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/definitions/00000000-0000-4000-8000-000000000000/reset-to-code" \
  -H "Accept: application/json"
GET/workflows/events

List all workflow events

Get a paginated list of all workflow events with filtering options

Parameters

NameInRequiredSchemaDescription
pagequeryNoany
pageSizequeryNoany
eventTypequeryNoany
workflowInstanceIdqueryNoany
userIdqueryNoany
occurredAtFromqueryNoany
occurredAtToqueryNoany
sortFieldqueryNoany
sortDirqueryNoany

Responses

200List of workflow events
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "workflowInstanceId": "00000000-0000-4000-8000-000000000000",
      "stepInstanceId": null,
      "eventType": "string",
      "occurredAt": "string",
      "userId": null,
      "workflowInstance": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/events?page=1&pageSize=50&sortField=occurredAt&sortDir=desc" \
  -H "Accept: application/json"
GET/workflows/events/{id}

Get workflow event by ID

Get detailed information about a specific workflow event

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Workflow event details
Content-Type: application/json
{
  "id": "string",
  "workflowInstanceId": "00000000-0000-4000-8000-000000000000",
  "stepInstanceId": null,
  "eventType": "string",
  "occurredAt": "string",
  "userId": null,
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "workflowInstance": null
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Workflow event not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/events/:id" \
  -H "Accept: application/json"
GET/workflows/instances

List workflow instances

Get a list of workflow instances with optional filters. Supports pagination and filtering by status, workflowId, correlationKey, etc.

Parameters

NameInRequiredSchemaDescription
workflowIdqueryNoany
statusqueryNoany
correlationKeyqueryNoany
entityTypequeryNoany
entityIdqueryNoany
limitqueryNoany
offsetqueryNoany

Responses

200List of workflow instances
Content-Type: application/json
{
  "data": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "definitionId": "00000000-0000-4000-8000-000000000000",
      "workflowId": "string",
      "version": 1,
      "status": "RUNNING",
      "currentStepId": "string",
      "correlationKey": null,
      "metadata": null,
      "startedAt": "string",
      "completedAt": null,
      "pausedAt": null,
      "cancelledAt": null,
      "errorMessage": null,
      "errorDetails": null,
      "pendingTransition": null,
      "retryCount": 1,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string",
      "deletedAt": null
    }
  ],
  "pagination": {
    "total": 1,
    "limit": 1,
    "offset": 1,
    "hasMore": true
  }
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/instances?limit=50&offset=0" \
  -H "Accept: application/json"
POST/workflows/instances

Start workflow instance

Start a new workflow instance from a workflow definition. The workflow will execute immediately.

Request body (application/json)

{
  "workflowId": "string"
}

Responses

201Workflow started successfully
Content-Type: application/json
{
  "data": {
    "instance": {
      "id": "00000000-0000-4000-8000-000000000000",
      "definitionId": "00000000-0000-4000-8000-000000000000",
      "workflowId": "string",
      "version": 1,
      "status": "RUNNING",
      "currentStepId": "string",
      "correlationKey": null,
      "metadata": null,
      "startedAt": "string",
      "completedAt": null,
      "pausedAt": null,
      "cancelledAt": null,
      "errorMessage": null,
      "errorDetails": null,
      "pendingTransition": null,
      "retryCount": 1,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string",
      "deletedAt": null
    },
    "execution": {
      "status": "RUNNING",
      "currentStep": "string",
      "message": "string"
    }
  },
  "message": "string"
}
400Bad request - Validation failed or definition disabled/invalid
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Workflow definition not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/instances" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"workflowId\": \"string\"
}"
GET/workflows/instances/{id}

Get workflow instance

Get detailed information about a specific workflow instance including current state, context, and execution status.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Workflow instance details
Content-Type: application/json
{
  "data": {
    "id": "00000000-0000-4000-8000-000000000000",
    "definitionId": "00000000-0000-4000-8000-000000000000",
    "workflowId": "string",
    "version": 1,
    "status": "RUNNING",
    "currentStepId": "string",
    "correlationKey": null,
    "metadata": null,
    "startedAt": "string",
    "completedAt": null,
    "pausedAt": null,
    "cancelledAt": null,
    "errorMessage": null,
    "errorDetails": null,
    "pendingTransition": null,
    "retryCount": 1,
    "tenantId": "00000000-0000-4000-8000-000000000000",
    "organizationId": "00000000-0000-4000-8000-000000000000",
    "createdAt": "string",
    "updatedAt": "string",
    "deletedAt": null
  }
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Workflow instance not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/instances/:id" \
  -H "Accept: application/json"
POST/workflows/instances/{id}/advance

Manually advance workflow to next step

Manually advance a workflow instance to the next step. Useful for manual progression, step-by-step testing, user-triggered transitions, and approval flows. Validates transitions and auto-progresses if possible.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{}

Responses

200Workflow advanced successfully
Content-Type: application/json
{
  "data": {
    "instance": {
      "id": "00000000-0000-4000-8000-000000000000",
      "status": "string",
      "currentStepId": null,
      "previousStepId": null,
      "transitionFired": null
    }
  },
  "message": "string"
}
400Invalid request, no valid transitions, or workflow already completed/cancelled/failed
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Workflow instance not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/instances/:id/advance" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/workflows/instances/{id}/cancel

Cancel workflow instance

Cancel a running or paused workflow instance. The workflow will be marked as CANCELLED and will not execute further.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Workflow cancelled successfully
Content-Type: application/json
{
  "data": {
    "id": "00000000-0000-4000-8000-000000000000",
    "definitionId": "00000000-0000-4000-8000-000000000000",
    "workflowId": "string",
    "version": 1,
    "status": "RUNNING",
    "currentStepId": "string",
    "correlationKey": null,
    "metadata": null,
    "startedAt": "string",
    "completedAt": null,
    "pausedAt": null,
    "cancelledAt": null,
    "errorMessage": null,
    "errorDetails": null,
    "pendingTransition": null,
    "retryCount": 1,
    "tenantId": "00000000-0000-4000-8000-000000000000",
    "organizationId": "00000000-0000-4000-8000-000000000000",
    "createdAt": "string",
    "updatedAt": "string",
    "deletedAt": null
  },
  "message": "string"
}
400Bad request - Workflow cannot be cancelled in current status
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Workflow instance not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/instances/:id/cancel" \
  -H "Accept: application/json"
GET/workflows/instances/{id}/events

Get workflow instance events

Get a chronological list of events for a workflow instance. Events track all state changes, transitions, and activities.

Parameters

NameInRequiredSchemaDescription
idpathYesany
eventTypequeryNoany
limitqueryNoany
offsetqueryNoany

Responses

200List of workflow events
Content-Type: application/json
{
  "data": [
    {
      "id": "string",
      "workflowInstanceId": "00000000-0000-4000-8000-000000000000",
      "stepInstanceId": null,
      "eventType": "string",
      "occurredAt": "string",
      "userId": null,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000"
    }
  ],
  "pagination": {
    "total": 1,
    "limit": 1,
    "offset": 1,
    "hasMore": true
  }
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Workflow instance not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/instances/:id/events?limit=100&offset=0" \
  -H "Accept: application/json"
POST/workflows/instances/{id}/retry

Retry failed workflow instance

Retry a failed workflow instance from its current step. The workflow will be reset to RUNNING status and execution will continue.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Responses

200Workflow retry initiated successfully
Content-Type: application/json
{
  "data": {
    "instance": {
      "id": "00000000-0000-4000-8000-000000000000",
      "definitionId": "00000000-0000-4000-8000-000000000000",
      "workflowId": "string",
      "version": 1,
      "status": "RUNNING",
      "currentStepId": "string",
      "correlationKey": null,
      "metadata": null,
      "startedAt": "string",
      "completedAt": null,
      "pausedAt": null,
      "cancelledAt": null,
      "errorMessage": null,
      "errorDetails": null,
      "pendingTransition": null,
      "retryCount": 1,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string",
      "deletedAt": null
    },
    "execution": {
      "status": "RUNNING",
      "currentStep": "string",
      "events": [
        {
          "eventType": "string",
          "occurredAt": "string"
        }
      ],
      "executionTime": 1
    }
  },
  "message": "string"
}
400Bad request - Workflow cannot be retried in current status or execution error
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Workflow instance not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/instances/:id/retry" \
  -H "Accept: application/json"
POST/workflows/instances/{id}/signal

Send signal to specific workflow

Sends a signal to a specific workflow instance waiting for a signal. The workflow must be in PAUSED status and waiting for the specified signal.

Parameters

NameInRequiredSchemaDescription
idpathYesany

Request body (application/json)

{
  "signalName": "string"
}

Responses

200Signal sent successfully
Content-Type: application/json
{
  "success": true,
  "message": "string"
}
400Invalid request body or signal name mismatch
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Instance or definition not found
Content-Type: application/json
{
  "error": "string"
}
409Workflow not paused or not waiting for signal
Content-Type: application/json
{
  "error": "string"
}
500Internal server error or transition failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/instances/:id/signal" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"signalName\": \"string\"
}"
POST/workflows/instances/validate-start

Validate if workflow can be started

Evaluates pre-conditions defined on the START step and returns validation errors with localized messages if any fail. Returns canStart: true/false with details.

Request body (application/json)

{
  "workflowId": "string"
}

Responses

200Validation result (canStart, errors, validatedRules)
Content-Type: application/json
{
  "canStart": true,
  "workflowId": "string"
}
400Invalid request body or missing context
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/instances/validate-start" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"workflowId\": \"string\"
}"
POST/workflows/signals

Send signal to workflows by correlation key

Sends a signal to all workflow instances waiting for the specified signal that match the correlation key. Returns the count of workflows that received the signal.

Request body (application/json)

{
  "correlationKey": "string",
  "signalName": "string"
}

Responses

200Signal sent to matching workflows
Content-Type: application/json
{
  "success": true,
  "message": "string",
  "count": 1
}
400Missing tenant or organization context
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://admin.getcovo.com/api/workflows/signals" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"correlationKey\": \"string\",
  \"signalName\": \"string\"
}"
GET/workflows/tasks

List user tasks

Returns paginated list of user tasks with optional filtering by status, assignee, workflow instance, overdue, and myTasks flags.

Parameters

NameInRequiredSchemaDescription
statusqueryNoanyFilter by status (comma-separated for multiple: PENDING,IN_PROGRESS,COMPLETED,CANCELLED,ESCALATED)
assignedToqueryNoanyFilter by assigned user ID
workflowInstanceIdqueryNoanyFilter by workflow instance ID
overduequeryNoanyFilter overdue tasks (true/false)
myTasksqueryNoanyShow only tasks assigned to or claimable by current user
limitqueryNoanyNumber of results (max 100)
offsetqueryNoanyPagination offset

Responses

200User tasks list with pagination
Content-Type: application/json
{
  "data": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "workflowInstanceId": "00000000-0000-4000-8000-000000000000",
      "stepInstanceId": "00000000-0000-4000-8000-000000000000",
      "taskName": "string",
      "description": null,
      "status": "PENDING",
      "formSchema": null,
      "formData": null,
      "assignedTo": null,
      "assignedToRoles": null,
      "claimedBy": null,
      "claimedAt": null,
      "dueDate": null,
      "escalatedAt": null,
      "escalatedTo": null,
      "completedBy": null,
      "completedAt": null,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "pagination": {
    "total": 1,
    "limit": 1,
    "offset": 1,
    "hasMore": true
  }
}
400Invalid query parameters or missing tenant context
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://admin.getcovo.com/api/workflows/tasks?limit=50&offset=0" \
  -H "Accept: application/json"