Documentation

API Reference

Programmatic access to issue, verify, and manage credentials at scale.

Authentication

REST v1 and SCIM requests require an organization API key. Generate one under Developer → API Keys in your issuer dashboard. Public credential, DID, status-list and OpenAPI endpoints do not require a key.

Request header

Authorization: Bearer cv_live_<your_api_key>

Keys are bound to one organization, with scopes, expiry and revocation. Use a separate key for each integration and grant only the scopes it needs. Passing an organization ID in a request does not change its authority.

REST API

Base URL: https://www.credverse.live/api/v1

Send JSON with Content-Type: application/json. Bodies are limited to 64 KiB; unknown properties and invalid UUIDs, emails and dates are rejected. Lists accept limit (1–100, default 50) and offset (0–1,000,000), and return {data, pagination: {limit, offset, hasMore}}. Credential lists also accept status and group_id. Pages can shift as new records arrive.

Retries and idempotency

Credential, group and webhook creation require Idempotency-Key: 8–128 letters, digits or ._:-. Reuse the same key and body when retrying a timeout or server error. Changed input under the same key returns 409. Credential signing completes before the transaction commits one credit debit, credential, audit record and webhook event. Successful retries return the original result. Revocation is permanent; issue a replacement to correct a revoked credential.

Issue a credential

Use a group in your organization. Omitted skills inherit the group defaults. Optional expiry_date is a future UTC YYYY-MM-DD; validity ends at its midnight. Store the returned credential ID and verification URL.

curl -X POST "https://www.credverse.live/api/v1/credentials" \
  -H "Authorization: Bearer $CREDVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: issue-jane-course-2026" \
  -d '{
    "group_id": "11111111-1111-4111-8111-111111111111",
    "holder_email": "recipient@example.com",
    "holder_name": "Jane Doe",
    "skills": ["Python", "AI"]
  }'

Success: 201 {id, verification_hash, verification_url, vc}, with Location and Idempotency-Replayed headers. Replace the example group UUID with your own.

Group creation accepts name, optional description (up to 4,000 characters), credential_type (certificate or badge) and up to 100 default_skills. Names are limited to 200 characters; each skill to 100. Webhook creation requires a URL and one or more event names (or * for all events). Analytics returns organization credential counts, group count and credit balance.

Endpoint reference

GET/api/v1/credentials

List organization credentials

Required scope: credentials:read

POST/api/v1/credentials

Create credentials

Required scope: credentials:write

GET/api/v1/credentials/{id}

Read organization resource

Required scope: credentials:read

PATCH/api/v1/credentials/{id}

Permanently revoke a credential

Required scope: credentials:revoke

{
  "status": "revoked"
}
GET/api/v1/groups

List organization groups

Required scope: groups:read

POST/api/v1/groups

Create groups

Required scope: groups:write

{
  "name": "Course completion",
  "description": "Completed the course",
  "credential_type": "certificate",
  "default_skills": [
    "Python"
  ]
}
GET/api/v1/groups/{id}

Read organization resource

Required scope: groups:read

GET/api/v1/webhooks

List organization webhooks

Required scope: webhooks:read

POST/api/v1/webhooks

Create webhooks

Required scope: webhooks:write

{
  "url": "https://receiver.example.com/credverse",
  "events": [
    "credential.issued",
    "credential.revoked"
  ]
}
GET/api/v1/webhooks/{id}

Read organization resource

Required scope: webhooks:read

PATCH/api/v1/webhooks/{id}

Enable or disable endpoint

Required scope: webhooks:write

{
  "is_active": false
}
DELETE/api/v1/webhooks/{id}

Delete endpoint and its delivery history

Required scope: webhooks:write

GET/api/v1/analytics

Organization credential counts and credit balance

Required scope: analytics:read

Rate limits and errors

REST and SCIM share a per-key budget of 100 reads and 20 writes per minute. A 429 response includes Retry-After in seconds. Responses include X-Request-ID for support correlation and use Cache-Control: no-store. Error bodies use {error, code, request_id}; SCIM uses its standard error schema.

Common API error statuses
StatusMeaning
400Invalid input, query or missing idempotency key
401 / 403Invalid key, missing scope or authority revoked during a write
402Insufficient credits; no credential committed
404Resource unavailable to this organization
409Idempotency or resource conflict
412SCIM version changed; fetch the latest resource
413 / 415Body exceeds 64 KiB or content type is unsupported
429Rate limit exceeded; respect Retry-After
500 / 503Server or dependency failure; retry with the original idempotency key

Webhooks

Receive HTTP POST notifications when credentials are issued, revoked, claimed, or expire. Configure webhooks from your dashboard under Developer → Webhooks, or via the REST API. Destinations must use public HTTPS on port 443. Private addresses and redirects are rejected.

Available Events

credential.issuedcredential.revokedcredential.expiredcredential.claimedcredential.viewedgroup.createdgroup.updatedorganization.member_addedorganization.member_removedcredits.lowcredits.purchased

Events are delivered at least once. Deduplicate by the authenticated event ID before side effects, and return 2xx only after accepting the work durably. Retries retain the original event ID and body, with up to five attempts and exponential delay. A failed delivery remains available for inspection. Creation responses include a signing secret, including identical idempotent replays; list/read responses omit it. Store the secret securely.

// Headers:
// X-CredVerse-Event: credential.issued
// X-CredVerse-Event-ID: <stable event UUID>
// X-CredVerse-Delivery-ID: <delivery UUID>
// X-CredVerse-Signature: t=<unix-seconds>,v1=<hex signature>
//
// Signed bytes: timestamp + "." + exact raw request body
// Expected signature: HMAC-SHA256(webhook_secret, signed bytes)
// Compare in constant time; reject timestamps outside a five-minute window.
// Do not parse and re-serialize JSON before verifying its signature.
// Body: {"id":"...","type":"credential.issued","timestamp":"...","data":{...}}

W3C Verifiable Credentials

New signed credentials use Ed25519 Data Integrity proofs with the eddsa-jcs-2022 cryptosuite. The proof covers the complete signed document. The verification endpoint returns that stored issuance snapshot; group edits and key rotation do not rewrite it. Historical public keys remain resolvable. Legacy proofs require an issuer signing upgrade before export.

GET/api/verify/{hash}

Returns the signed VC 2.0 JSON-LD snapshot for a visible credential. Requires a 64-character hex hash; 30 reads/minute/IP. Legacy records awaiting upgrade return 503.

Public endpoint — no API key required

curl "https://www.credverse.live/api/verify/$VERIFICATION_HASH" -H "Accept: application/ld+json"
GET/api/status-list/{orgId}

Returns the signed W3C Bitstring Status List for the organization. HTTP cache: 60 seconds; signed verifier TTL: five minutes. The current list supports 131,071 allocated slots per organization; exhaustion rejects issuance before charging.

Public endpoint — no API key required

GET/api/did/{orgId}

Returns the current issuer DID document. Versioned did:web keys resolve at /org/{slug}/{version}/did.json; historical public keys are retained.

Public endpoint — no API key required

A valid signature alone does not establish current validity. Verifiers must also check validUntil and the referenced revocation list, with an issuer they trust. Rotation preserves historical verification; compromised-key recovery requires revoking affected credentials and issuing replacements.

SCIM 2.0 User Provisioning

Provision issuer memberships with an organization API key containing scim:read and scim:write. Configure your identity provider's base URL as https://www.credverse.live/api/scim/v2 and use that key as its Bearer token. Test your IdP's configuration before enabling production synchronization.

This SCIM subset supports user lifecycle management, equality filters and ETags. It does not provide SAML/OIDC sign-in, groups, bulk operations, sorting or password changes. Global SCIM tokens are no longer accepted. Existing manually managed memberships and holder identities require explicit enrollment; they are not automatically adopted.

curl -X POST "https://www.credverse.live/api/scim/v2/Users" \
  -H "Authorization: Bearer $CREDVERSE_SCIM_KEY" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "userName": "jane@example.com",
    "displayName": "Jane Doe",
    "externalId": "employee-123",
    "active": true
  }'
  • List only this organization's SCIM-managed users. Use count (0–100), startIndex (1-based), or one equality filter, such as userName eq "jane@example.com". Other supported attributes are emails.value, externalId, id and active. Unsupported filters return an error.
  • PATCH supports active, displayName, name.formattedand externalId. userName is immutable; returned emails reflect it.
  • User responses include an ETag such as W/"2". Send it in If-Matchwhen updating; stale writes return 412 without changing the user. Conditional PUT/PATCH success returns 204 with the new ETag; GET the user for its updated representation. Updates without If-Match return 200 and the resource. Attribute projection on updates is unsupported.
  • Deactivation or deletion removes only the membership provisioned by SCIM. It preserves the global identity and other organizations. Owners must transfer ownership before deprovisioning.
GET/api/scim/v2/Users

List organization SCIM users

Required scope: scim:read

POST/api/scim/v2/Users

Provision an issuer membership

Required scope: scim:write

GET/api/scim/v2/Users/{id}

SCIM membership lifecycle

Required scope: scim:read

PATCH/api/scim/v2/Users/{id}

SCIM membership lifecycle

Required scope: scim:write

{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:PatchOp"
  ],
  "Operations": [
    {
      "op": "replace",
      "path": "active",
      "value": false
    }
  ]
}
PUT/api/scim/v2/Users/{id}

SCIM membership lifecycle

Required scope: scim:write

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "userName": "jane@example.com",
  "displayName": "Jane Doe",
  "active": true
}
DELETE/api/scim/v2/Users/{id}

SCIM membership lifecycle

Required scope: scim:write

GET/api/scim/v2/ServiceProviderConfig

SCIM capability discovery

Required scope: scim:read

GET/api/scim/v2/ResourceTypes

SCIM capability discovery

Required scope: scim:read

GET/api/scim/v2/ResourceTypes/User

SCIM capability discovery

Required scope: scim:read

GET/api/scim/v2/Schemas

SCIM capability discovery

Required scope: scim:read

GET/api/scim/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User

SCIM capability discovery

Required scope: scim:read

Ready to build?

Create a free account and generate your first API key in minutes.

Get your API keys

No credit card required