Verification API
Public endpoints for checking license validity. These endpoints don't require authentication, allowing your software to verify licenses from anywhere.
Get Public Key
Fetch the RSA public key for offline verification:
GET /api/v1/apps/:slug/public-key
$ curl https://license.yourapp.com/api/v1/apps/my-app/public-key
# Response (Content-Type: application/x-pem-file)
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2K3...
-----END PUBLIC KEY----- Verify License
Check license status by installation_id or JTI:
GET /api/v1/apps/:slug/licenses/verify
# By installation_id
$ curl "https://license.yourapp.com/api/v1/apps/my-app/licenses/verify?installation_id=550e8400-e29b-41d4-a716-446655440000"
# Or by JTI (JWT ID)
$ curl "https://license.yourapp.com/api/v1/apps/my-app/licenses/verify?jti=lic_abc123xyz"
# Response
{
"data": {
"valid": true,
"status": "active",
"tier": "pro",
"features": ["api_access", "export"],
"expires_at": "2027-01-23T00:00:00Z",
"installation_id": "550e8400-e29b-41d4-a716-446655440000"
}
} Response Fields
| Field | Type | Description |
|---|---|---|
valid | boolean | Whether the license is currently valid |
status | string | "active", "expired", or "revoked" |
tier | string | Tier slug |
features | string[] | Enabled feature slugs |
expires_at | datetime? | Expiration timestamp (null for forever licenses) |
Batch Verify
Verify multiple licenses in a single request (max 100):
POST /api/v1/apps/:slug/licenses/verify/batch
$ curl -X POST https://license.yourapp.com/api/v1/apps/my-app/licenses/verify/batch \
-H "Content-Type: application/json" \
-d '{
"installation_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001"
]
}'
# Or by JTIs
{
"jtis": ["lic_abc123", "lic_def456"]
}
# Response
{
"data": {
"results": {
"550e8400-e29b-41d4-a716-446655440000": {
"valid": true,
"status": "active",
"tier": "pro"
},
"660e8400-e29b-41d4-a716-446655440001": {
"valid": false,
"status": "expired",
"tier": "free"
}
}
},
"meta": {
"total": 2,
"valid_count": 1,
"invalid_count": 1
}
} Rate Limits
Public verification endpoints are rate limited per IP address:
Single Verify
100 requests/minute
Batch Verify
20 requests/minute
429 Too Many Requests
Response
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again later."
}
} Online vs Offline Verification
Online (API)
- Real-time revocation checks
- Latest license data
- Requires network
Offline (JWT)
- Works without network
- Instant verification
- Can't check revocation
Health Check
Monitor your Blackwalnut instance:
GET /api/health
$ curl https://license.yourapp.com/api/health
{
"status": "ok",
"timestamp": "2026-01-23T10:00:00Z"
}