openapi: 3.0.3 info: title: Sertifier Credential API description: >- The Sertifier Credential API lets backend systems and LMS/CRM integrations programmatically design, issue, verify, and manage verifiable digital credentials (certificates and badges) on the Sertifier platform. A credential is issued inside a Campaign that binds three things: a visual Design, a descriptive Detail, and an Email Template used to deliver the finished credential to a Recipient. Custom Attributes are merged into the design and email at issue time. All requests are sent to the base host with a private API key in the `secretKey` header and an `api-version` header. Most responses share a common envelope ({ message, hasError, validationErrors, data, content }). All dates are UTC. Designs are authored in the Sertifier web application; the API references and duplicates them. Endpoint paths, methods, the base host (https://b2b.sertifier.com), the `secretKey` / `api-version` headers, and the credential-issuance workflow are grounded in Sertifier's public Apiary reference, help-center quickstart, and integration guides. Request and response bodies are minimally modeled where the public reference does not fully enumerate every field; those are marked with `x-modeled: true`. version: '3.3' contact: name: Sertifier url: https://sertifier.com email: support@sertifier.com x-logo: url: https://kinlane-images.s3.amazonaws.com/shared/apis-json/apis-json-logo.jpg servers: - url: https://b2b.sertifier.com description: Sertifier Credential API (production) security: - secretKey: [] tags: - name: Authentication description: Verify API key validity. - name: Campaigns description: Containers that bind a Design, Detail, and Email Template and issue credentials. - name: Credentials description: Individual issued credentials - retrieve, update, publish, and generate PDF links. - name: Designs description: Visual designs applied to certificates and badges. - name: Details description: Descriptive metadata (title, skills, criteria) printed on a credential. - name: Email Templates description: Templates used to deliver finished credentials to recipients. - name: Recipients description: Learners who receive credentials. - name: Attributes description: Reusable custom key/value fields merged into credentials. - name: Webhooks description: MODELED - inbound/outbound event automation. Not confirmed in the public reference. paths: /Test: get: operationId: testAuthentication tags: - Authentication summary: Verify API key description: Verifies that the provided secretKey is valid. parameters: - $ref: '#/components/parameters/ApiVersion' responses: '200': description: The API key is valid. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /campaign: post: operationId: createCampaign tags: - Campaigns summary: Create a campaign description: >- Creates a credential campaign, referencing a Design ID, a Detail ID, and an Email Template ID. Returns the created campaign including its campaignId, which is used to issue credentials. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CampaignCreate' responses: '200': description: The created campaign. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /campaign/{campaignId}: get: operationId: getCampaign tags: - Campaigns summary: Retrieve a campaign parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/CampaignId' responses: '200': description: The requested campaign. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' put: operationId: updateCampaign tags: - Campaigns summary: Update a campaign parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/CampaignId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CampaignCreate' responses: '200': description: The updated campaign. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' delete: operationId: deleteCampaign tags: - Campaigns summary: Delete a campaign parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/CampaignId' responses: '200': description: The campaign was deleted. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /campaign/search: post: operationId: searchCampaigns tags: - Campaigns summary: Search campaigns description: Returns a paginated list of campaigns matching the search filters. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of campaigns. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /campaign/addCredentials: post: operationId: addCredentials tags: - Campaigns summary: Add / issue credentials to a campaign description: >- Issues one or more credentials into a campaign. Each credential references the campaignId and a recipient (name + email) plus optional custom attributes, external ID, issue date, and publish flags. Set quickPublish=true to publish immediately. Use an idempotency check on (enrolment ID + campaignId) if your source event can fire more than once. The response includes the permanent, verifiable credential URL. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AddCredentialsRequest' responses: '200': description: The issued credentials, including permanent credential URLs. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /campaign/send: post: operationId: sendCampaign tags: - Campaigns summary: Publish / send a campaign's credentials description: Publishes the credentials in a campaign and sends delivery emails. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: type: object properties: campaignId: type: string required: - campaignId responses: '200': description: The campaign's credentials were published. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /campaign/schedule: post: operationId: scheduleCampaign tags: - Campaigns summary: Schedule credential distribution description: Schedules a campaign's credential distribution at a future UTC time. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: type: object properties: campaignId: type: string scheduleDate: type: string format: date-time description: The UTC time at which to distribute credentials. required: - campaignId - scheduleDate responses: '200': description: The campaign distribution was scheduled. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /credential/{credentialId}: get: operationId: getCredential tags: - Credentials summary: Retrieve a credential parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/CredentialId' responses: '200': description: The requested credential. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' put: operationId: updateCredential tags: - Credentials summary: Update a credential parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/CredentialId' requestBody: required: true content: application/json: schema: type: object x-modeled: true responses: '200': description: The updated credential. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' delete: operationId: deleteCredential tags: - Credentials summary: Delete a credential parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/CredentialId' responses: '200': description: The credential was deleted. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /credential/search: post: operationId: searchCredentials tags: - Credentials summary: Search credentials description: Returns a paginated list of issued credentials matching the filters. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of credentials. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /credential/publish: post: operationId: publishCredentials tags: - Credentials summary: Publish credentials description: Publishes one or more credentials, making their verifiable URLs live. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: type: object properties: credentialIds: type: array items: type: string responses: '200': description: The credentials were published. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /credential/generatePDFLink/{credentialIdOrCertificateNo}: get: operationId: generatePdfLink tags: - Credentials summary: Generate a credential PDF link description: >- Generates a downloadable PDF link for a credential, identified by its credential ID or its certificate number. parameters: - $ref: '#/components/parameters/ApiVersion' - name: credentialIdOrCertificateNo in: path required: true description: The credential ID or the certificate number. schema: type: string responses: '200': description: A downloadable PDF link for the credential. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /design/{designId}: get: operationId: getDesign tags: - Designs summary: Retrieve a design parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/DesignId' responses: '200': description: The requested design. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' delete: operationId: deleteDesign tags: - Designs summary: Delete a design parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/DesignId' responses: '200': description: The design was deleted. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /design/search: post: operationId: searchDesigns tags: - Designs summary: Search designs description: Returns a paginated list of designs. Designs are authored in the web app. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of designs. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /design/copy: post: operationId: copyDesign tags: - Designs summary: Copy a design description: Duplicates an existing design. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: type: object properties: designId: type: string required: - designId responses: '200': description: The duplicated design. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /detail: post: operationId: createDetail tags: - Details summary: Create a credential detail description: >- Creates a credential Detail - the title, description, skills, and criteria printed on a credential. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Detail' responses: '200': description: The created detail. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /detail/{detailId}: get: operationId: getDetail tags: - Details summary: Retrieve a credential detail parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/DetailId' responses: '200': description: The requested detail. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' put: operationId: updateDetail tags: - Details summary: Update a credential detail description: Updates a Detail. Details become immutable once their credentials are sent. parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/DetailId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Detail' responses: '200': description: The updated detail. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /detail/search: post: operationId: searchDetails tags: - Details summary: Search credential details parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of details. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /detail/searchSkills: post: operationId: searchSkills tags: - Details summary: Search the skills library description: Searches Sertifier's skills library to attach skills to a credential detail. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of matching skills. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /emailTemplate/{emailTemplateId}: get: operationId: getEmailTemplate tags: - Email Templates summary: Retrieve an email template parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/EmailTemplateId' responses: '200': description: The requested email template. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' delete: operationId: deleteEmailTemplate tags: - Email Templates summary: Delete an email template parameters: - $ref: '#/components/parameters/ApiVersion' - $ref: '#/components/parameters/EmailTemplateId' responses: '200': description: The email template was deleted. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /emailTemplate/search: post: operationId: searchEmailTemplates tags: - Email Templates summary: Search email templates parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of email templates. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /emailTemplate/copy: post: operationId: copyEmailTemplate tags: - Email Templates summary: Copy an email template parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: type: object properties: emailTemplateId: type: string required: - emailTemplateId responses: '200': description: The duplicated email template. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /recipient: post: operationId: addRecipient tags: - Recipients summary: Add a recipient parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Recipient' responses: '200': description: The created recipient. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' put: operationId: updateRecipient tags: - Recipients summary: Update recipient(s) parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Recipient' responses: '200': description: The updated recipient(s). content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /recipient/{recipientId}: delete: operationId: deleteRecipient tags: - Recipients summary: Delete a recipient parameters: - $ref: '#/components/parameters/ApiVersion' - name: recipientId in: path required: true schema: type: string responses: '200': description: The recipient was deleted. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /recipient/search: post: operationId: searchRecipients tags: - Recipients summary: Search recipients parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of recipients. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /attribute: post: operationId: createAttribute tags: - Attributes summary: Create a custom attribute parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Attribute' responses: '200': description: The created attribute. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /attribute/{attributeId}: put: operationId: updateAttribute tags: - Attributes summary: Update a custom attribute parameters: - $ref: '#/components/parameters/ApiVersion' - name: attributeId in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Attribute' responses: '200': description: The updated attribute. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' delete: operationId: deleteAttribute tags: - Attributes summary: Delete a custom attribute parameters: - $ref: '#/components/parameters/ApiVersion' - name: attributeId in: path required: true schema: type: string responses: '200': description: The attribute was deleted. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /attribute/search: post: operationId: searchAttributes tags: - Attributes summary: Search custom attributes parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' responses: '200': description: A paginated list of attributes. content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' /webhook: post: operationId: createWebhook tags: - Webhooks summary: Create a webhook subscription (MODELED) description: >- MODELED, NOT CONFIRMED. A first-party outbound webhook subscription resource is not published in Sertifier's Credential API reference as of the review date. Sertifier documents receiving inbound completion events and no-code automation (Zapier, n8n) rather than a documented REST webhook-subscription endpoint. This operation is included as an honest placeholder and should be verified before use. parameters: - $ref: '#/components/parameters/ApiVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Webhook' responses: '200': description: The created webhook subscription (modeled). content: application/json: schema: $ref: '#/components/schemas/Envelope' '401': $ref: '#/components/responses/Unauthorized' components: securitySchemes: secretKey: type: apiKey in: header name: secretKey description: >- Private API key obtained from the Sertifier web application under Settings > API & Integrations (also referenced as Advanced > Integrations). Store it in a secrets vault; never embed it in client-side JavaScript. parameters: ApiVersion: name: api-version in: header required: true description: API version header. Current documented value is 3.3. schema: type: string default: '3.3' CampaignId: name: campaignId in: path required: true schema: type: string CredentialId: name: credentialId in: path required: true schema: type: string DesignId: name: designId in: path required: true schema: type: string DetailId: name: detailId in: path required: true schema: type: string EmailTemplateId: name: emailTemplateId in: path required: true schema: type: string responses: Unauthorized: description: The secretKey is missing or invalid. content: application/json: schema: $ref: '#/components/schemas/Envelope' schemas: Envelope: type: object description: Standard Sertifier response envelope. properties: message: type: string nullable: true hasError: type: boolean validationErrors: type: array items: type: string data: nullable: true description: The operation-specific payload (object or array). content: nullable: true SearchRequest: type: object description: Paginated search request. x-modeled: true properties: page: type: integer default: 1 pageSize: type: integer default: 20 query: type: string nullable: true CampaignCreate: type: object properties: name: type: string designId: type: string description: The Design applied to credentials issued in this campaign. detailId: type: string description: The credential Detail printed on the credential. emailTemplateId: type: string description: The Email Template used to deliver the credential. required: - designId - emailTemplateId AddCredentialsRequest: type: object properties: campaignId: type: string description: The campaign container to issue credentials into. credentials: type: array items: $ref: '#/components/schemas/CredentialInput' required: - campaignId - credentials CredentialInput: type: object properties: name: type: string description: The recipient's full name. email: type: string format: email description: The recipient's email address. issueDate: type: string format: date description: The credential issue date (UTC). quickPublish: type: boolean description: Publish the credential immediately. dontSendEmail: type: boolean description: Suppress Sertifier's delivery email. externalId: type: string description: A reference ID from your own system, useful for idempotency. updateExistingCredentials: type: boolean description: Update a matching existing credential instead of creating a duplicate. attributes: type: array description: Custom attribute values merged into the design and email. items: type: object properties: id: type: string value: type: string required: - name - email Detail: type: object x-modeled: true properties: title: type: string description: type: string skills: type: array items: type: string criteria: type: string Recipient: type: object x-modeled: true properties: id: type: string name: type: string email: type: string format: email Attribute: type: object x-modeled: true properties: id: type: string name: type: string value: type: string Webhook: type: object x-modeled: true description: MODELED - not confirmed in the public Sertifier API reference. properties: url: type: string format: uri events: type: array items: type: string