Credentials
The Credentials endpoints allow you to issue, verify, revoke, and manage PASETO v4 signed Verifiable Credentials.
Issue a Credential
Section titled “Issue a Credential”Creates and signs a PASETO v4 Verifiable Credential with the specified subject data.
POST /v1/credentialsAuthentication
Section titled “Authentication”Requires BearerAuth or ApiKeyAuth.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
issuer_did | string | Yes | DID of the credential issuer |
issuer_private_key | string | Yes | Base64-encoded private key for signing |
subject_did | string | Yes | DID of the credential subject |
credential_type | string | Yes | Type of credential (e.g., “EmploymentCredential”) |
claims | object | Yes | Custom claims/attributes for the credential |
expiration_date | string | No | ISO 8601 expiration date |
Request Example
Section titled “Request Example”curl -X POST "https://api.veriglob.com/v1/credentials" \ -H "Authorization: Bearer your-api-key" \ -H "Content-Type: application/json" \ -d '{ "issuer_did": "did:key:z6MkissuerDID...", "issuer_private_key": "base64-encoded-private-key", "subject_did": "did:key:z6MksubjectDID...", "credential_type": "EmploymentCredential", "claims": { "employer": "Acme Corporation", "position": "Software Engineer", "start_date": "2024-01-15" }, "expiration_date": "2025-01-15T00:00:00Z" }'interface IssueCredentialRequest { issuer_did: string; issuer_private_key: string; subject_did: string; credential_type: string; claims: Record<string, unknown>; expiration_date?: string;}
interface IssueCredentialResponse {status: string;message: string;data: {credential_id: string;credential: string;issuer: string;subject: string;credential_type: string;issued_at: string;expires_at?: string;};}
async function issueCredential(apiKey: string,request: IssueCredentialRequest): Promise<IssueCredentialResponse> {const response = await fetch('https://api.veriglob.com/v1/credentials', {method: 'POST',headers: {'Authorization': `Bearer ${apiKey}`,'Content-Type': 'application/json'},body: JSON.stringify(request)});
if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}return response.json();}
// Usageconst result = await issueCredential('your-api-key', {issuer_did: 'did:key:z6MkissuerDID...',issuer_private_key: 'base64-encoded-private-key',subject_did: 'did:key:z6MksubjectDID...',credential_type: 'EmploymentCredential',claims: { employer: 'Acme Corp', position: 'Engineer' },expiration_date: new Date(Date.now() + 365 _ 24 _ 60 _ 60 _ 1000).toISOString()});console.log('Credential ID:', result.data.credential_id);package main
import ( "bytes" "encoding/json" "net/http" "time")
type IssueCredentialRequest struct { IssuerDID string `json:"issuer_did"` IssuerPrivateKey string `json:"issuer_private_key"` SubjectDID string `json:"subject_did"` CredentialType string `json:"credential_type"` Claims map[string]interface{} `json:"claims"` ExpirationDate string `json:"expiration_date,omitempty"`}
type IssueCredentialResponse struct { Status string `json:"status"` Message string `json:"message"` Data struct { CredentialID string `json:"credential_id"` Credential string `json:"credential"` Issuer string `json:"issuer"` Subject string `json:"subject"` CredentialType string `json:"credential_type"` IssuedAt string `json:"issued_at"` ExpiresAt string `json:"expires_at,omitempty"` } `json:"data"`}
func IssueCredential(apiKey string, req IssueCredentialRequest) (*IssueCredentialResponse, error) { jsonData, _ := json.Marshal(req) request, _ := http.NewRequest("POST", "https://api.veriglob.com/v1/credentials", bytes.NewBuffer(jsonData)) request.Header.Set("Authorization", "Bearer "+apiKey) request.Header.Set("Content-Type", "application/json")
client := &http.Client{} resp, err := client.Do(request) if err != nil { return nil, err } defer resp.Body.Close()
var result IssueCredentialResponse json.NewDecoder(resp.Body).Decode(&result) return &result, nil}
// Usagefunc main() { expiration := time.Now().AddDate(1, 0, 0).Format(time.RFC3339) result, _ := IssueCredential("your-api-key", IssueCredentialRequest{ IssuerDID: "did:key:z6MkissuerDID...", IssuerPrivateKey: "base64-encoded-private-key", SubjectDID: "did:key:z6MksubjectDID...", CredentialType: "EmploymentCredential", Claims: map[string]interface{}{"employer": "Acme Corp"}, ExpirationDate: expiration, }) println("Credential ID:", result.Data.CredentialID)}import requestsfrom datetime import datetime, timedeltafrom typing import Dict, Any, Optional
def issue_credential(api_key: str,issuer_did: str,issuer_private_key: str,subject_did: str,credential_type: str,claims: Dict[str, Any],expiration_date: Optional[str] = None) -> dict:"""Issue a verifiable credential."""payload = {'issuer_did': issuer_did,'issuer_private_key': issuer_private_key,'subject_did': subject_did,'credential_type': credential_type,'claims': claims,}if expiration_date:payload['expiration_date'] = expiration_date
response = requests.post( 'https://api.veriglob.com/v1/credentials', headers={'Authorization': f'Bearer {api_key}'}, json=payload ) response.raise_for_status() return response.json()
# Usage
expiration = (datetime.utcnow() + timedelta(days=365)).isoformat() + 'Z'result = issue_credential(api_key='your-api-key',issuer_did='did:key:z6MkissuerDID...',issuer_private_key='base64-encoded-private-key',subject_did='did:key:z6MksubjectDID...',credential_type='EmploymentCredential',claims={'employer': 'Acme Corp', 'position': 'Engineer'},expiration_date=expiration)print(f"Credential ID: {result['data']['credential_id']}")Response
Section titled “Response”201 Created
{ "status": "success", "message": "Credential issued successfully", "data": { "credential_id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", "credential": "v4.public.eyJpc3MiOiJkaWQ6a2V5Ono2TWtoLi4uIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6a2V5Ono2TWsuLi4ifX0...", "issuer": "did:key:z6MkissuerDID...", "subject": "did:key:z6MksubjectDID...", "credential_type": "EmploymentCredential", "issued_at": "2024-01-15T10:30:00Z", "expires_at": "2025-01-15T00:00:00Z" }}Error Responses
Section titled “Error Responses”| Status | Description |
|---|---|
| 400 | Invalid request body or missing required fields |
| 401 | Invalid or missing API key |
| 429 | Rate limit exceeded |
Verify a Credential
Section titled “Verify a Credential”Verifies a PASETO v4 credential signature and optionally checks revocation status.
POST /v1/credentials/verifyAuthentication
Section titled “Authentication”Requires BearerAuth or ApiKeyAuth.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
credential | string | Yes | The PASETO v4 credential token |
issuer_did | string | Yes | DID of the expected issuer |
check_revocation | boolean | No | Whether to check revocation status (default: false) |
Request Example
Section titled “Request Example”curl -X POST "https://api.veriglob.com/v1/credentials/verify" \ -H "Authorization: Bearer your-api-key" \ -H "Content-Type: application/json" \ -d '{ "credential": "v4.public.eyJpc3MiOi...", "issuer_did": "did:key:z6MkissuerDID...", "check_revocation": true }'interface VerifyCredentialRequest { credential: string; issuer_did: string; check_revocation?: boolean;}
interface VerifyCredentialResponse {status: string;message: string;data: {valid: boolean;issuer?: string;subject?: string;credential_type?: string;claims?: Record<string, unknown>;revoked?: boolean;expired?: boolean;error?: string;};}
async function verifyCredential(apiKey: string,request: VerifyCredentialRequest): Promise<VerifyCredentialResponse> {const response = await fetch('https://api.veriglob.com/v1/credentials/verify', {method: 'POST',headers: {'Authorization': `Bearer ${apiKey}`,'Content-Type': 'application/json'},body: JSON.stringify(request)});
if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}return response.json();}
// Usageconst result = await verifyCredential('your-api-key', {credential: 'v4.public.eyJpc3MiOi...',issuer_did: 'did:key:z6MkissuerDID...',check_revocation: true});
if (result.data.valid) {console.log('Credential is valid!');console.log('Claims:', result.data.claims);} else {console.log('Invalid:', result.data.error);}type VerifyCredentialRequest struct { Credential string `json:"credential"` IssuerDID string `json:"issuer_did"` CheckRevocation bool `json:"check_revocation,omitempty"`}
type VerifyCredentialResponse struct { Status string `json:"status"` Message string `json:"message"` Data struct { Valid bool `json:"valid"` Issuer string `json:"issuer,omitempty"` Subject string `json:"subject,omitempty"` CredentialType string `json:"credential_type,omitempty"` Claims map[string]interface{} `json:"claims,omitempty"` Revoked bool `json:"revoked,omitempty"` Expired bool `json:"expired,omitempty"` Error string `json:"error,omitempty"` } `json:"data"`}
func VerifyCredential(apiKey string, req VerifyCredentialRequest) (*VerifyCredentialResponse, error) { jsonData, _ := json.Marshal(req) request, _ := http.NewRequest("POST", "https://api.veriglob.com/v1/credentials/verify", bytes.NewBuffer(jsonData)) request.Header.Set("Authorization", "Bearer "+apiKey) request.Header.Set("Content-Type", "application/json")
client := &http.Client{} resp, err := client.Do(request) if err != nil { return nil, err } defer resp.Body.Close()
var result VerifyCredentialResponse json.NewDecoder(resp.Body).Decode(&result) return &result, nil}def verify_credential( api_key: str, credential: str, issuer_did: str, check_revocation: bool = False) -> dict: """Verify a credential's signature and optionally check revocation.""" response = requests.post( 'https://api.veriglob.com/v1/credentials/verify', headers={'Authorization': f'Bearer {api_key}'}, json={ 'credential': credential, 'issuer_did': issuer_did, 'check_revocation': check_revocation } ) response.raise_for_status() return response.json()
# Usage
result = verify_credential(api_key='your-api-key',credential='v4.public.eyJpc3MiOi...',issuer_did='did:key:z6MkissuerDID...',check_revocation=True)
if result['data']['valid']:print('Credential is valid!')print(f"Claims: {result['data']['claims']}")else:print(f"Invalid: {result['data'].get('error')}")Response
Section titled “Response”200 OK (Valid)
{ "status": "success", "message": "Credential verified successfully", "data": { "valid": true, "issuer": "did:key:z6MkissuerDID...", "subject": "did:key:z6MksubjectDID...", "credential_type": "EmploymentCredential", "claims": { "employer": "Acme Corporation", "position": "Software Engineer" }, "revoked": false, "expired": false }}200 OK (Invalid)
{ "status": "success", "message": "Credential verification completed", "data": { "valid": false, "error": "Signature verification failed" }}Error Responses
Section titled “Error Responses”| Status | Description |
|---|---|
| 400 | Invalid credential format or missing fields |
| 401 | Invalid or missing API key |
| 429 | Rate limit exceeded |
| 500 | Internal server error during verification |
Revoke a Credential
Section titled “Revoke a Credential”Marks a credential as revoked in the revocation registry.
POST /v1/credentials/revoke/{credential_id}Authentication
Section titled “Authentication”Requires BearerAuth or ApiKeyAuth.
Path Parameters
Section titled “Path Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
credential_id | string | Yes | The credential ID to revoke |
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Reason for revocation |
issuer_did | string | Yes | DID of the issuer (for authorization) |
Request Example
Section titled “Request Example”curl -X POST "https://api.veriglob.com/v1/credentials/revoke/urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5" \ -H "Authorization: Bearer your-api-key" \ -H "Content-Type: application/json" \ -d '{ "reason": "Employment terminated", "issuer_did": "did:key:z6MkissuerDID..." }'async function revokeCredential( apiKey: string, credentialId: string, issuerDid: string, reason?: string) { const response = await fetch( `https://api.veriglob.com/v1/credentials/revoke/${encodeURIComponent(credentialId)}`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ issuer_did: issuerDid, reason }) } ); return response.json();}
// Usageconst result = await revokeCredential('your-api-key','urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5','did:key:z6MkissuerDID...','Employment terminated');func RevokeCredential(apiKey, credentialID, issuerDID, reason string) error { payload := map[string]string{ "issuer_did": issuerDID, "reason": reason, } jsonData, _ := json.Marshal(payload)
url := "https://api.veriglob.com/v1/credentials/revoke/" + url.PathEscape(credentialID) req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json")
client := &http.Client{} _, err := client.Do(req) return err}from urllib.parse import quote
def revoke_credential(api_key: str,credential_id: str,issuer_did: str,reason: str = None) -> dict:"""Revoke a credential."""payload = {'issuer_did': issuer_did}if reason:payload['reason'] = reason
response = requests.post( f'https://api.veriglob.com/v1/credentials/revoke/{quote(credential_id, safe="")}', headers={'Authorization': f'Bearer {api_key}'}, json=payload ) response.raise_for_status() return response.json()
# Usage
result = revoke_credential(api_key='your-api-key',credential_id='urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5',issuer_did='did:key:z6MkissuerDID...',reason='Employment terminated')Response
Section titled “Response”200 OK
{ "status": "success", "message": "Credential revoked successfully", "data": { "credential_id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", "revoked": true, "revoked_at": "2024-06-15T14:30:00Z", "reason": "Employment terminated" }}Error Responses
Section titled “Error Responses”| Status | Description |
|---|---|
| 400 | Invalid credential ID or missing issuer_did |
| 401 | Invalid or missing API key |
| 403 | Not authorized to revoke this credential |
| 404 | Credential not found |
| 429 | Rate limit exceeded |
Check Revocation Status
Section titled “Check Revocation Status”Returns the current status of a credential in the revocation registry.
GET /v1/credentials/status/{credential_id}Request Example
Section titled “Request Example”curl -X GET "https://api.veriglob.com/v1/credentials/status/urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5" \ -H "Authorization: Bearer your-api-key"async function checkRevocationStatus(apiKey: string, credentialId: string) { const response = await fetch( `https://api.veriglob.com/v1/credentials/status/${encodeURIComponent(credentialId)}`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); return response.json();}func CheckRevocationStatus(apiKey, credentialID string) (*StatusResponse, error) { url := "https://api.veriglob.com/v1/credentials/status/" + url.PathEscape(credentialID) req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close()
var result StatusResponse json.NewDecoder(resp.Body).Decode(&result) return &result, nil
}def check_revocation_status(api_key: str, credential_id: str) -> dict: """Check if a credential has been revoked.""" response = requests.get( f'https://api.veriglob.com/v1/credentials/status/{quote(credential_id, safe="")}', headers={'Authorization': f'Bearer {api_key}'} ) response.raise_for_status() return response.json()Response
Section titled “Response”200 OK (Active)
{ "status": "success", "message": "Credential status retrieved", "data": { "credential_id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", "revoked": false }}200 OK (Revoked)
{ "status": "success", "message": "Credential status retrieved", "data": { "credential_id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", "revoked": true, "revoked_at": "2024-06-15T14:30:00Z", "reason": "Employment terminated" }}List Credentials by Issuer
Section titled “List Credentials by Issuer”Returns all credentials issued by the specified DID.
GET /v1/credentials/by-issuer/{issuer_did}Request Example
Section titled “Request Example”curl -X GET "https://api.veriglob.com/v1/credentials/by-issuer/did:key:z6MkissuerDID..." \ -H "Authorization: Bearer your-api-key"async function listCredentialsByIssuer(apiKey: string, issuerDid: string) { const response = await fetch( `https://api.veriglob.com/v1/credentials/by-issuer/${encodeURIComponent(issuerDid)}`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); return response.json();}func ListCredentialsByIssuer(apiKey, issuerDID string) (*ListCredentialsResponse, error) { url := "https://api.veriglob.com/v1/credentials/by-issuer/" + url.PathEscape(issuerDID) req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{} resp, _ := client.Do(req) defer resp.Body.Close()
var result ListCredentialsResponse json.NewDecoder(resp.Body).Decode(&result) return &result, nil
}def list_credentials_by_issuer(api_key: str, issuer_did: str) -> dict: """List all credentials issued by a DID.""" response = requests.get( f'https://api.veriglob.com/v1/credentials/by-issuer/{quote(issuer_did, safe="")}', headers={'Authorization': f'Bearer {api_key}'} ) response.raise_for_status() return response.json()Response
Section titled “Response”{ "status": "success", "message": "Credentials retrieved successfully", "data": { "credentials": [ { "credential_id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", "subject": "did:key:z6MksubjectDID1...", "credential_type": "EmploymentCredential", "issued_at": "2024-01-15T10:30:00Z", "revoked": false } ], "total": 1 }}List Credentials by Subject
Section titled “List Credentials by Subject”Returns all credentials where the specified DID is the subject.
GET /v1/credentials/by-subject/{subject_did}Credential Types
Section titled “Credential Types”Common credential types supported:
| Type | Description |
|---|---|
VerifiableCredential | Generic verifiable credential |
EmploymentCredential | Employment verification |
EducationCredential | Educational achievement |
MembershipCredential | Organization membership |
IdentityCredential | Identity verification |
AgeVerificationCredential | Age verification |
You can also define custom credential types by providing any string value.