{"openapi":"3.0.3","info":{"title":"Cohiva Credentials — Public API","version":"1.1.0","description":"Headless, API-first verifiable-credential platform (Open Badges 2.0). Authenticate every partner call with your issuer API key as `Authorization: Bearer <key>` or `X-API-Key: <key>`. The key resolves your issuer, so issuer-scoped calls never take an issuer id. Mutations are recorded in an append-only audit log. Every authenticated endpoint is rate-limited per key: on a `429 Too Many Requests` a `Retry-After` header gives the back-off in seconds (the official `@cohiva/credentials-sdk` honours it with exponential back-off automatically). A recipient email is only ever hashed (salted SHA-256) and is never stored or returned raw."},"servers":[{"url":"https://api.credentials.cohiva.com"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"},"BearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"Unauthorized":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"The resource does not exist (or is not visible to this issuer).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"BadRequest":{"description":"The request body or query failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"RateLimited":{"description":"Rate limit exceeded for this API key. Retry after the number of seconds in the `Retry-After` header. `X-RateLimit-*` headers describe the current window.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Max requests allowed in the window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"QuotaExceeded":{"description":"The issuer has exhausted its plan issuance quota for the period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaError"}}}},"PremiumRequired":{"description":"The issuer’s plan does not include premium verification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"IssueRequest":{"type":"object","required":["definitionId","recipientEmail","completionKey"],"properties":{"definitionId":{"type":"string","format":"uuid"},"recipientEmail":{"type":"string","format":"email","description":"Hashed (salted SHA-256) immediately; never stored raw."},"recipientName":{"type":"string"},"completionKey":{"type":"string","description":"Idempotency key — re-issuing the same key returns the existing credential."},"evidenceUrl":{"type":"string","format":"uri"}}},"CompletionEvent":{"type":"object","required":["recipientEmail"],"properties":{"definitionId":{"type":"string","format":"uuid"},"definitionRef":{"type":"string","description":"Credential type by slug or name (when no definitionId)."},"recipientEmail":{"type":"string","format":"email"},"recipientName":{"type":"string"},"completionKey":{"type":"string"},"issuedOn":{"type":"string","format":"date-time"},"evidenceUrl":{"type":"string","format":"uri"}}},"CsvImportRequest":{"type":"object","required":["csv"],"properties":{"csv":{"type":"string","description":"Raw CSV text (header row required; a leading UTF-8 BOM is stripped)."},"filename":{"type":"string"},"dryRun":{"type":"boolean","description":"When true, returns a preview (rows classified new/duplicate/already_issued/error) without issuing."},"mapping":{"type":"object","properties":{}},"defaults":{"type":"object","properties":{"definitionId":{"type":"string"},"definitionRef":{"type":"string"}}}}},"DefinitionRequest":{"type":"object","required":["name","description"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"slug":{"type":"string"},"criteriaNarrative":{"type":"string"},"criteriaUrl":{"type":"string","format":"uri"},"imageUrl":{"type":"string","format":"uri"},"tags":{"type":"array","items":{"type":"string"}},"skills":{"type":"array","items":{"type":"string"}},"expiresAfterDays":{"type":"integer","nullable":true}}},"VerifyRequest":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"The assertion id (its resolvable HTTPS URL)."}}},"BulkVerifyRequest":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","items":{"type":"string"}}}},"RevokeRequest":{"type":"object","properties":{"reason":{"type":"string"}}},"ReissueRequest":{"type":"object","properties":{"completionKey":{"type":"string"},"evidenceUrl":{"type":"string","format":"uri"}}},"ProgressRequest":{"type":"object","required":["recipientEmail"],"properties":{"recipientEmail":{"type":"string","format":"email","description":"Hashed for lookup; never stored or returned raw."}}},"PathwayRequest":{"type":"object","required":["name","description"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"slug":{"type":"string"}}},"PathwayStageRequest":{"type":"object","required":["definitionId","stepOrder"],"properties":{"definitionId":{"type":"string"},"stepOrder":{"type":"integer"},"required":{"type":"boolean"}}},"EndorsementRequest":{"type":"object","required":["endorserName","claim"],"properties":{"endorserName":{"type":"string"},"endorserUrl":{"type":"string","format":"uri"},"claim":{"type":"string"}}},"AlignmentRequest":{"type":"object","required":["targetName","targetUrl"],"properties":{"targetName":{"type":"string"},"targetUrl":{"type":"string","format":"uri"},"targetFramework":{"type":"string"},"targetCode":{"type":"string"},"targetDescription":{"type":"string"}}},"JobReadyReceiveRequest":{"type":"object","required":["records"],"properties":{"records":{"type":"array","items":{"type":"object","properties":{}},"description":"ReadyTech/JobReady completion records (the pushed payload)."},"mapping":{"type":"object","properties":{}},"definitionMap":{"type":"object","additionalProperties":{"type":"string"},"description":"ReadyTech course/qualification code → credential definition slug/id."}}},"Issuer":{"type":"object","required":["id","slug","name","profileUrl"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"profileUrl":{"type":"string","format":"uri","description":"Resolvable HTTPS OB 2.0 Issuer Profile id."}}},"IssuedCredential":{"type":"object","required":["credentialId","assertionUrl","badgeClassUrl","created"],"properties":{"credentialId":{"type":"string"},"assertionUrl":{"type":"string","format":"uri","description":"Resolvable HTTPS OB 2.0 Assertion id (the credential’s canonical URL)."},"badgeClassUrl":{"type":"string","format":"uri"},"verifyUrl":{"type":"string","format":"uri","description":"Human verification page (QR/share target).","nullable":true},"status":{"type":"string","enum":["valid","expired","revoked"]},"created":{"type":"boolean","description":"true if newly issued, false on an idempotent replay of an existing credential."}}},"IngestResult":{"allOf":[{"$ref":"#/components/schemas/IssuedCredential"},{"type":"object","properties":{"completionKey":{"type":"string"},"outcome":{"type":"string","enum":["issued","skipped","error"]}}}],"description":"An issued credential plus the per-event ingest outcome."},"ImportRowReport":{"type":"object","required":["rowNum","outcome"],"properties":{"rowNum":{"type":"integer"},"outcome":{"type":"string","enum":["issued","skipped","error"]},"completionKey":{"type":"string","nullable":true},"credentialId":{"type":"string","nullable":true},"message":{"type":"string","nullable":true}}},"ImportReport":{"type":"object","required":["batchId","total","issued","skipped","errored","rows"],"properties":{"batchId":{"type":"string"},"source":{"type":"string"},"filename":{"type":"string","nullable":true},"total":{"type":"integer"},"issued":{"type":"integer"},"skipped":{"type":"integer"},"errored":{"type":"integer"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/ImportRowReport"}}}},"Definition":{"type":"object","required":["id","issuerId","slug","name","description"],"properties":{"id":{"type":"string"},"issuerId":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"criteriaNarrative":{"type":"string","nullable":true},"criteriaUrl":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"skills":{"type":"array","items":{"type":"string"}},"expiresAfterDays":{"type":"integer","nullable":true},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CredentialSummary":{"type":"object","required":["id","status","definitionId","assertionUrl","badgeClassUrl","issuedOn","completionKey"],"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["valid","expired","revoked"]},"definitionId":{"type":"string"},"assertionUrl":{"type":"string","format":"uri"},"badgeClassUrl":{"type":"string","format":"uri"},"verifyUrl":{"type":"string","format":"uri","nullable":true},"issuedOn":{"type":"string","format":"date-time"},"expiresOn":{"type":"string","format":"date-time","nullable":true},"revokedAt":{"type":"string","format":"date-time","nullable":true},"completionKey":{"type":"string"}}},"CredentialPage":{"type":"object","required":["total","limit","offset","items"],"properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/CredentialSummary"}}}},"CredentialDetail":{"type":"object","required":["id","status","assertionUrl","badgeClassUrl","issuedOn","completionKey"],"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["valid","expired","revoked"]},"assertionUrl":{"type":"string","format":"uri"},"badgeClassUrl":{"type":"string","format":"uri"},"verifyUrl":{"type":"string","format":"uri","nullable":true},"issuedOn":{"type":"string","format":"date-time"},"expiresOn":{"type":"string","format":"date-time","nullable":true},"revokedAt":{"type":"string","format":"date-time","nullable":true},"revokedReason":{"type":"string","nullable":true},"completionKey":{"type":"string"}}},"RevokeResult":{"type":"object","required":["credentialId","status","revokedAt"],"properties":{"credentialId":{"type":"string"},"status":{"type":"string","enum":["revoked"]},"revokedAt":{"type":"string","format":"date-time"},"revokedReason":{"type":"string","nullable":true}}},"VerificationResult":{"type":"object","required":["id","authentic","status","valid"],"properties":{"id":{"type":"string","description":"The assertion id (resolvable HTTPS URL) that was checked."},"authentic":{"type":"boolean","description":"True when the id resolves to an assertion this service hosts."},"status":{"type":"string","enum":["valid","expired","revoked","unknown"]},"valid":{"type":"boolean"},"issuer":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"profileUrl":{"type":"string","format":"uri"},"brandPrimaryColor":{"type":"string","nullable":true},"brandLogoUrl":{"type":"string","nullable":true}}},"credential":{"type":"object","properties":{"name":{"type":"string"},"badgeClassUrl":{"type":"string","format":"uri"}}},"recipientName":{"type":"string","description":"PARTIAL only — first name + last initial (privacy); never the raw email."},"issuedOn":{"type":"string","format":"date-time"},"expiresOn":{"type":"string","format":"date-time","nullable":true},"revokedReason":{"type":"string","nullable":true},"verifyPageUrl":{"type":"string","format":"uri"}}},"BulkVerifyResult":{"type":"object","required":["count","results"],"properties":{"count":{"type":"integer"},"results":{"type":"array","items":{"$ref":"#/components/schemas/VerificationResult"}}}},"ConnectorRecordReport":{"type":"object","required":["index","outcome"],"properties":{"index":{"type":"integer"},"outcome":{"type":"string","enum":["issued","skipped","error"]},"completionKey":{"type":"string","nullable":true},"credentialId":{"type":"string","nullable":true},"message":{"type":"string","nullable":true}}},"ConnectorRunReport":{"type":"object","required":["provider","total","issued","skipped","errored","records"],"properties":{"provider":{"type":"string"},"total":{"type":"integer"},"issued":{"type":"integer"},"skipped":{"type":"integer"},"errored":{"type":"integer"},"records":{"type":"array","items":{"$ref":"#/components/schemas/ConnectorRecordReport"}}}},"UsageSummary":{"type":"object","required":["planCode","issuanceUsed","premiumVerification","periodStart","metering","generatedAt"],"properties":{"planCode":{"type":"string"},"issuanceQuota":{"type":"integer","description":"null = unlimited.","nullable":true},"issuanceUsed":{"type":"integer"},"issuanceRemaining":{"type":"integer","nullable":true},"premiumVerification":{"type":"boolean"},"periodStart":{"type":"string","format":"date-time"},"metering":{"type":"object","properties":{"issuance":{"type":"integer"},"premiumVerification":{"type":"integer"}}},"generatedAt":{"type":"string","format":"date-time"}}},"RecipientExport":{"type":"object","required":["found","recipientHash","credentials"],"properties":{"found":{"type":"boolean"},"recipientHash":{"type":"string","description":"Salted SHA-256 of the email (pseudonymous; the raw email is never stored)."},"displayName":{"type":"string","nullable":true},"credentials":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"definitionId":{"type":"string"},"assertionUrl":{"type":"string","format":"uri"},"issuedOn":{"type":"string","format":"date-time"},"expiresOn":{"type":"string","format":"date-time","nullable":true},"revokedAt":{"type":"string","format":"date-time","nullable":true},"completionKey":{"type":"string"}}}}}},"RecipientErasure":{"type":"object","required":["found","revoked","credentialIds"],"properties":{"found":{"type":"boolean"},"revoked":{"type":"integer","description":"Count of credentials revoked."},"credentialIds":{"type":"array","items":{"type":"string"}}}},"ReportDefinitionBreakdown":{"type":"object","required":["definitionId","name","slug","issued","valid","expired","revoked","verifies"],"properties":{"definitionId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"issued":{"type":"integer"},"valid":{"type":"integer"},"expired":{"type":"integer"},"revoked":{"type":"integer"},"verifies":{"type":"integer"}}},"IssuanceReport":{"type":"object","required":["issuerId","totals","byDefinition","generatedAt"],"properties":{"issuerId":{"type":"string"},"window":{"type":"object","properties":{"from":{"type":"string","format":"date-time","nullable":true},"to":{"type":"string","format":"date-time","nullable":true}}},"totals":{"type":"object","properties":{"issued":{"type":"integer"},"valid":{"type":"integer"},"expired":{"type":"integer"},"revoked":{"type":"integer"},"issuedInWindow":{"type":"integer"},"verifies":{"type":"integer"},"imports":{"type":"object","properties":{"batches":{"type":"integer"},"issued":{"type":"integer"},"skipped":{"type":"integer"},"errored":{"type":"integer"}}}}},"verifiesByChannel":{"type":"object","properties":{"api":{"type":"integer"},"bulk":{"type":"integer"},"page":{"type":"integer"}}},"byDefinition":{"type":"array","items":{"$ref":"#/components/schemas/ReportDefinitionBreakdown"}},"generatedAt":{"type":"string","format":"date-time"}}},"TimePoint":{"type":"object","required":["date","count"],"properties":{"date":{"type":"string","description":"UTC day, YYYY-MM-DD."},"count":{"type":"integer"}}},"AnalyticsDefinitionRow":{"type":"object","required":["definitionId","name","slug"],"properties":{"definitionId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"issued":{"type":"integer"},"valid":{"type":"integer"},"expired":{"type":"integer"},"revoked":{"type":"integer"},"verifies":{"type":"integer"},"shares":{"type":"integer"}}},"AnalyticsPathwayRow":{"type":"object","required":["pathwayId","name","slug"],"properties":{"pathwayId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"stages":{"type":"integer"},"issued":{"type":"integer"},"recipients":{"type":"integer"}}},"AnalyticsGeoRow":{"type":"object","required":["country","count"],"properties":{"country":{"type":"string"},"count":{"type":"integer"}}},"EngagementByAction":{"type":"object","required":["linkedin","wallet_apple","wallet_google","share_link","total"],"properties":{"linkedin":{"type":"integer"},"wallet_apple":{"type":"integer"},"wallet_google":{"type":"integer"},"share_link":{"type":"integer"},"total":{"type":"integer"}}},"IssuerAnalytics":{"type":"object","required":["issuerId","window","totals","series","generatedAt"],"properties":{"issuerId":{"type":"string"},"window":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"totals":{"type":"object","properties":{"issued":{"type":"integer"},"valid":{"type":"integer"},"expired":{"type":"integer"},"revoked":{"type":"integer"},"issuedInWindow":{"type":"integer"},"verifies":{"type":"integer"},"shares":{"type":"integer"}}},"verifiesByChannel":{"type":"object","properties":{"api":{"type":"integer"},"bulk":{"type":"integer"},"page":{"type":"integer"}}},"engagementByAction":{"$ref":"#/components/schemas/EngagementByAction"},"funnel":{"type":"object","properties":{"issued":{"type":"integer"},"verified":{"type":"integer"},"shared":{"type":"integer"}}},"series":{"type":"object","properties":{"issuance":{"type":"array","items":{"$ref":"#/components/schemas/TimePoint"}},"verifies":{"type":"array","items":{"$ref":"#/components/schemas/TimePoint"}},"engagement":{"type":"array","items":{"$ref":"#/components/schemas/TimePoint"}}}},"byDefinition":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsDefinitionRow"}},"byPathway":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsPathwayRow"}},"geo":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsGeoRow"}},"generatedAt":{"type":"string","format":"date-time"}}},"Pathway":{"type":"object","required":["id","issuerId","slug","name"],"properties":{"id":{"type":"string"},"issuerId":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PathwayStage":{"type":"object","required":["id","pathwayId","definitionId","stepOrder","required"],"properties":{"id":{"type":"string"},"pathwayId":{"type":"string"},"definitionId":{"type":"string"},"stepOrder":{"type":"integer"},"required":{"type":"boolean"}}},"PathwayWithStages":{"allOf":[{"$ref":"#/components/schemas/Pathway"},{"type":"object","required":["stages"],"properties":{"stages":{"type":"array","items":{"$ref":"#/components/schemas/PathwayStage"}}}}]},"WebhookCatalogEvent":{"type":"object","required":["event","description","sample"],"properties":{"event":{"type":"string","description":"The event name (e.g. credential.issued)."},"description":{"type":"string"},"sample":{"type":"object","required":["id","event","occurredAt","data"],"properties":{"id":{"type":"string"},"event":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{}}}}}},"WebhookCatalog":{"type":"object","required":["signature","headers","retry","events"],"properties":{"signature":{"type":"object","required":["header","scheme","algorithm","signedOver"],"properties":{"header":{"type":"string"},"scheme":{"type":"string"},"algorithm":{"type":"string"},"signedOver":{"type":"string"}}},"headers":{"type":"object","properties":{}},"retry":{"type":"object","required":["maxAttempts","backoffMinutes","note"],"properties":{"maxAttempts":{"type":"integer"},"backoffMinutes":{"type":"array","items":{"type":"integer"}},"note":{"type":"string"}}},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookCatalogEvent"}}}},"PathwayProgress":{"type":"object","required":["pathwayId","name","complete","earnedStages","totalStages","requiredStages","stages"],"properties":{"pathwayId":{"type":"string"},"name":{"type":"string"},"complete":{"type":"boolean"},"earnedStages":{"type":"integer"},"totalStages":{"type":"integer"},"requiredStages":{"type":"integer"},"stages":{"type":"array","items":{"type":"object","properties":{"stageId":{"type":"string"},"definitionId":{"type":"string"},"stepOrder":{"type":"integer"},"required":{"type":"boolean"},"earned":{"type":"boolean"}}}}}},"Endorsement":{"type":"object","required":["id","issuerId","targetType","targetId","endorserName","claim","createdAt"],"properties":{"id":{"type":"string"},"issuerId":{"type":"string"},"targetType":{"type":"string","enum":["definition","credential"]},"targetId":{"type":"string"},"endorserName":{"type":"string"},"endorserUrl":{"type":"string","format":"uri","nullable":true},"claim":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"Alignment":{"type":"object","required":["id","issuerId","definitionId","targetName","targetUrl","createdAt"],"properties":{"id":{"type":"string"},"issuerId":{"type":"string"},"definitionId":{"type":"string"},"targetName":{"type":"string"},"targetUrl":{"type":"string","format":"uri"},"targetFramework":{"type":"string","nullable":true},"targetCode":{"type":"string","nullable":true},"targetDescription":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string"}}},"ValidationError":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{}},"description":"Zod validation issues."}}},"QuotaError":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string","enum":["quota_exceeded"]},"message":{"type":"string"},"plan":{"type":"string"},"quota":{"type":"integer","nullable":true},"used":{"type":"integer"}}}}},"paths":{"/api/v1/issuer/me":{"get":{"summary":"Resolve the issuer for the presented API key","tags":["Issuer"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"The authenticated issuer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Issuer"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/credentials":{"post":{"summary":"Issue a credential","tags":["Credentials"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueRequest"}}}},"responses":{"200":{"description":"Already issued (idempotent replay).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedCredential"}}}},"201":{"description":"Issued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedCredential"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"summary":"List issued credentials (paginated + filterable)","tags":["Credentials"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"status","in":"query","schema":{"type":"string","enum":["valid","expired","revoked"]}},{"name":"definitionId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialPage"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/credentials/{id}":{"get":{"summary":"Get a credential","tags":["Credentials"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The credential.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/credentials/{id}/revoke":{"post":{"summary":"Revoke a credential","tags":["Credentials"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeRequest"}}}},"responses":{"200":{"description":"Revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/credentials/{id}/reissue":{"post":{"summary":"Reissue a credential (fresh assertion id)","tags":["Credentials"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReissueRequest"}}}},"responses":{"201":{"description":"Reissued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedCredential"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/definitions":{"post":{"summary":"Create a credential definition (OB BadgeClass)","tags":["Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DefinitionRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Definition"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Slug already taken.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"summary":"List credential definitions","tags":["Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"The issuer’s definitions.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Definition"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/definitions/{id}":{"get":{"summary":"Get a credential definition","tags":["Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The definition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Definition"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/ingest/csv":{"post":{"summary":"CSV / manual import → batch issue (idempotent, per-row report). Set dryRun for a no-issue preview.","tags":["Ingest"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportRequest"}}}},"responses":{"200":{"description":"Import report (or a dry-run preview when dryRun=true).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportReport"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"description":"Invalid CSV.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/ingest/completions":{"post":{"summary":"Generic REST ingest of a single completion event","tags":["Ingest"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionEvent"}}}},"responses":{"200":{"description":"Already issued (idempotent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}}}},"201":{"description":"Issued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"description":"Ingest failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/connectors/jobready/completions":{"post":{"summary":"ReadyTech / JobReady RECEIVE webhook — map pushed completion events → idempotent issuance","tags":["Connectors"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobReadyReceiveRequest"}}}},"responses":{"200":{"description":"Connector run report (issued/skipped/errored).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectorRunReport"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/connectors/{provider}/completions":{"post":{"summary":"Generic LMS/SMS connector RECEIVE (aXcelerate / eSkilled / generic) on the shared ingest seam","tags":["Connectors"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["axcelerate","eskilled","generic"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobReadyReceiveRequest"}}}},"responses":{"200":{"description":"Connector run report.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectorRunReport"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Unknown connector provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/verify":{"post":{"summary":"Verify a credential by assertion id (no auth)","tags":["Verification"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}}},"responses":{"200":{"description":"Verification result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/api/v1/verify/bulk":{"post":{"summary":"Bulk-verify assertion ids (no auth) — results returned in the same order","tags":["Verification"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkVerifyRequest"}}}},"responses":{"200":{"description":"Results in order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkVerifyResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/api/v1/webhooks/catalog":{"get":{"summary":"The public webhooks-out catalog (no auth): subscribable events, signature scheme, headers, retry policy","tags":["Webhooks"],"responses":{"200":{"description":"The webhook event catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCatalog"}}}}}}},"/api/v1/verify/premium":{"post":{"summary":"Premium verification (authed, entitlement-gated, metered) — same result, reserved for plans that include it","tags":["Verification"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}}},"responses":{"200":{"description":"Verification result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PremiumRequired"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/usage":{"get":{"summary":"The issuer’s own usage + plan (quota, consumption this period)","tags":["Usage"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Usage summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/gdpr/export":{"post":{"summary":"GDPR — export everything held for a recipient (email in body, hashed for lookup; raw email never stored/returned)","tags":["GDPR"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgressRequest"}}}},"responses":{"200":{"description":"The recipient’s held data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientExport"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/gdpr/erase":{"post":{"summary":"GDPR — erase a recipient: null the personal label + revoke their credentials + audit (append-only record kept)","tags":["GDPR"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgressRequest"}}}},"responses":{"200":{"description":"Erasure result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientErasure"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/reports/issuance":{"get":{"summary":"Per-issuer operational report (issuance / lifecycle / verifies / by definition)","tags":["Reports"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Issuer report.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuanceReport"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/reports/issuance.csv":{"get":{"summary":"CSV export of the per-definition issuance report","tags":["Reports"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"text/csv attachment.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/analytics":{"get":{"summary":"SQL-aggregated, time-series analytics (issuance/verifies/engagement over time, funnel, by-definition + by-pathway, geo)","tags":["Analytics"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Issuer analytics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuerAnalytics"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/analytics.csv":{"get":{"summary":"CSV export of the analytics time-series (one row per UTC day) — the schedulable export","tags":["Analytics"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"text/csv attachment.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/pathways":{"post":{"summary":"CR-DEF+ — create a credential pathway (staged)","tags":["Pathways"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pathway"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Slug taken.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"summary":"List credential pathways","tags":["Pathways"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Pathways.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Pathway"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/pathways/{id}":{"get":{"summary":"Get a pathway with its stages","tags":["Pathways"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pathway + stages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayWithStages"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/pathways/{id}/stages":{"post":{"summary":"Add a stage (definition) to a pathway","tags":["Pathways"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayStageRequest"}}}},"responses":{"201":{"description":"Stage added.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayStage"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/pathways/{id}/progress":{"post":{"summary":"A recipient’s progress through a pathway (email in body, hashed)","tags":["Pathways"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgressRequest"}}}},"responses":{"200":{"description":"Progress.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayProgress"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/definitions/{id}/endorsements":{"post":{"summary":"CR-DEF+ — endorse a definition (badge type)","tags":["Endorsements"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndorsementRequest"}}}},"responses":{"201":{"description":"Endorsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Endorsement"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"summary":"List endorsements of a definition","tags":["Endorsements"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Endorsements.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Endorsement"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/credentials/{id}/endorsements":{"post":{"summary":"CR-DEF+ — endorse a single credential","tags":["Endorsements"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndorsementRequest"}}}},"responses":{"201":{"description":"Endorsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Endorsement"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"summary":"List endorsements of a credential","tags":["Endorsements"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Endorsements.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Endorsement"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/definitions/{id}/alignments":{"post":{"summary":"CR-DEF+ — add a framework alignment to a definition","tags":["Alignments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlignmentRequest"}}}},"responses":{"201":{"description":"Added.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alignment"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"summary":"List a definition’s framework alignments","tags":["Alignments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Alignments.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Alignment"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}}}}