Issue verifiable credentials from your code
The SwanShare REST API lets you issue tamper-evident, publicly verifiable credentials programmatically — from your LMS, backend, or a tool like Zapier. Every credential is cryptographically signed and instantly verifiable by anyone, with no account.
Base URL
https://www.swanshare.site/apiAuthentication
Authenticate with an API key as a Bearer token. Create and manage keys in your dashboard under Settings → API keys. The full key (swan_sk_…) is shown once at creation — store it securely.
Authorization: Bearer swan_sk_your_key_hereTreat keys like passwords. They grant full issuing access for your organization.
Issue credentials
Issue one credential, or many in a batch by sending an items array. Each credential needs at least recipient_name and title.
Single
curl -X POST https://www.swanshare.site/api/v1/credentials \
-H "Authorization: Bearer swan_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"recipient_name": "Asha Rao",
"recipient_email": "[email protected]",
"title": "Advanced Data Analytics",
"expires_at": "2027-12-31",
"fields": { "Score": "A+", "Hours": "120" }
}'Batch (a whole cohort)
{
"items": [
{ "recipient_name": "Asha Rao", "title": "Advanced Data Analytics" },
{ "recipient_name": "Vikram Singh", "title": "Advanced Data Analytics" }
]
}Response — 201 Created
{
"ok": true,
"count": 2,
"credentials": [
{ "verify_id": "a1b2c3…", "verify_url": "https://www.swanshare.site/verify?id=a1b2c3…" },
{ "verify_id": "d4e5f6…", "verify_url": "https://www.swanshare.site/verify?id=d4e5f6…" }
]
}Fetch a credential
Re-run the full verification (signature, hash, ledger inclusion, revocation/expiry) for a credential and get the canonical result.
curl https://www.swanshare.site/api/v1/credentials/a1b2c3… \
-H "Authorization: Bearer swan_sk_your_key_here"{
"valid": true,
"status": "valid",
"checks": [ { "name": "Signature", "passed": true, "detail": "…" } ],
"credential": { "title": "Advanced Data Analytics", "recipient_name": "Asha Rao", "issued_at": "…" },
"issuer": { "name": "Acme Training Co.", "verified": true }
}Errors & limits
Errors return a JSON body with an error message and an appropriate status code.
- 401Missing or invalid API key.
- 402Monthly plan limit reached (response includes "limit": true). Upgrade to issue more.
- 400Each credential needs recipient_name and title.
Rate limit: 120 requests / minute per API key.
Webhooks
Register endpoints in Settings → API keys to be notified of events. SwanShare sends a POST with a JSON body and these headers:
X-SwanShare-Event: credential.issued
X-SwanShare-Signature: sha256=<hmac>Events
- credential.issued — one or more credentials were issued
- document.signed — all recipients signed a document
Payload
{
"event": "credential.issued",
"data": {
"count": 1,
"credentials": [
{ "verify_id": "a1b2c3…", "verify_url": "https://www.swanshare.site/verify?id=a1b2c3…" }
]
}
}Verify the signature
Each request is signed with HMAC-SHA256 over the raw body using your endpoint's signing secret. Recompute it and compare:
import hmac, hashlib
def is_valid(raw_body: bytes, header_sig: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header_sig)