HomeGuidesAPI ReferenceChangelog
Home
Guides

Card Issuance KYC API Access Webhook

Purpose: Provide a complete reference for the card_issuance_api_access_updated webhook event so integrators can correctly interpret entity-level Card Issuance KYC compliance status changes and respond to feature access grants, revocations, and individual requirement rejections.


ℹ️

The Notifications API is available only for the KYCaaS and Universal KYC verification methods. Webhook notifications are triggered exclusively for these two verification flows.

When You'll Receive This Notification

Consult this reference when you need to:

  • Interpret a card_issuance_api_access_updated event received on your registered webhook endpoint
  • Determine whether the event represents an individual requirement rejection or an overall feature access change
  • Map RequirementStatus enum values (APPROVED, PENDING, REJECTED) to application behaviour for card issuance features
  • Identify the cause of a rejection from the reviewRejectType and rejectLabels fields and decide whether retry or support escalation is required
  • Implement or validate a consumer that automatically enables or disables card issuance functionality for an entity based on its compliance status

Overview

The Card Issuance KYC API access notification is sent when an entity's compliance status changes in a way that affects access to card issuance functionality. The event is delivered through Reap's consolidated notification system, which automatically determines the appropriate event details and message based on the entity's compliance state at the time the change occurs.

Notifications are emitted at two distinct granularities. Requirement-level rejections are sent for individual requirements that fail verification so the integrator knows exactly what needs to be fixed. Feature-level access changes are sent when overall access to the Card Issuance KYC API is granted, updated, or revoked. Individual requirement approvals are intentionally not sent — notifications are only emitted when the entire feature becomes ready to use, which keeps the notification volume low.

The status field is always present and uses the RequirementStatus enum, allowing consumers to switch on a single field to determine handling. Optional fields (moderationComment, reviewRejectType, rejectLabels, requirementId, slug) provide additional context depending on the type of event being delivered.


Event Identification

FieldValue
eventTypeaccount_status_change
eventNamecard_issuance_api_access_updated

Notification Strategy

The notification system follows three rules that together determine when and how a webhook is emitted for an entity.

Requirement Rejections

  • Emitted whenever an individual requirement is rejected
  • Includes the requirementId and slug fields so the integrator can identify the specific requirement that failed
  • Allows the integrator to surface targeted remediation guidance to the end user

Feature Access Changes

  • Emitted when overall feature access is granted, updated, or revoked at the entity level
  • Used to enable or disable card issuance functionality in the integrator's application
  • Distinguishable from requirement rejections by the absence of requirementId and slug

No Spam on Individual Approvals

  • Individual requirement approvals do not trigger a notification
  • A notification is only emitted once the entire feature is ready to use
  • Keeps notification volume aligned with actionable changes only

Webhook Payload Structure

When an entity's Card Issuance KYC API access status changes, Reap delivers a POST request to the registered webhook endpoint with the following payload shape.

{
  "eventType": "account_status_change",
  "eventName": "card_issuance_api_access_updated",
  "data": {
    "message": "Card Issuance KYC API access updated",
    "entityId": "ent_123e4567-e89b-12d3-a456-426614174000",
    "status": "APPROVED",
    "moderationComment": "Identity verification approved by compliance team",
    "reviewRejectType": "RETRY",
    "rejectLabels": ["DOCUMENT_QUALITY"],
    "timestamp": "2024-03-20T10:00:00Z"
  }
}

Payload Field Reference

Top-Level Fields

FieldTypeRequiredDescriptionExample
eventTypestringAlways account_status_change"account_status_change"
eventNamestringAlways card_issuance_api_access_updated"card_issuance_api_access_updated"
dataobjectEvent-specific payload objectSee data fields below

data (object)

FieldTypeRequiredDescriptionExample
eventIdstringUnique ID for this notification — use for deduplication"b610f044-6a99-4803-84c0-78ea79912929"
messagestringHuman-readable message describing the change"Card Issuance KYC API access granted"
entityIdstringUUID of the entity whose compliance status changed"ent_123e4567-e89b-12d3-a456-426614174000"
statusstringCurrent compliance status from the RequirementStatus enum (always present)"APPROVED", "PENDING", or "REJECTED"
moderationCommentstringComment from the compliance team"Identity verification approved by compliance team"
reviewRejectTypestringType of rejection (only present for rejected status)"FINAL" or "RETRY"
rejectLabelsstring[]Specific rejection reasons (only present for rejections)["DOCUMENT_QUALITY", "EXPIRED_DOCUMENT"]
requirementIdstringUUID of the specific requirement that was rejected (only present for individual requirement rejections)"req_456e7890-f12c-34d5-b678-901234567890"
slugstringSlug identifying the rejected requirement (only present for individual requirement rejections)"individual-verification-identity"
timestampstringISO 8601 timestamp when the event occurred"2024-03-20T10:00:00Z"
ℹ️

The status field is always present and required in every Card Issuance KYC API notification. It uses the RequirementStatus enum values APPROVED, PENDING, or REJECTED, so consumers can safely branch on this single field.


Conditional Field Presence

The optional fields in the data object are populated according to the type of event being delivered. The table below summarises which fields to expect in each case.

Event VariantstatusmoderationCommentreviewRejectTyperejectLabelsrequirementIdslug
Access granted (auto-enabled)APPROVEDOptionalAbsentAbsentAbsentAbsent
Access granted (manual approval)APPROVEDTypically presentAbsentAbsentAbsentAbsent
Pending reviewPENDINGOptionalAbsentAbsentAbsentAbsent
Individual requirement rejectedREJECTEDTypically presentPresentPresentPresentPresent
Feature access revokedREJECTEDTypically presentPresentPresentAbsentAbsent
ℹ️

The presence of requirementId and slug is the canonical way to distinguish an individual requirement rejection from a full feature access revocation. Consumers should branch on these fields when handling REJECTED status.


Enumeration Reference

Status Values (RequirementStatus)

StatusDescriptionWhen It Occurs
APPROVEDRequirement successfully metWhen KYC verification passes all checks
PENDINGAwaiting review or processingWhen requirement is submitted but not yet processed
REJECTEDRequirement failed verificationWhen KYC verification fails or is rejected

Review Reject Type Values

TypeDescriptionAction Required
FINALPermanent rejection, no further attempts allowedContact support for clarification
RETRYTemporary rejection, can resubmit with correctionsAddress the issues and resubmit

Common Reject Labels

When a requirement is rejected, the rejectLabels array may contain one or more of the following values.

LabelDescription
DOCUMENT_QUALITYDocument image quality is insufficient
EXPIRED_DOCUMENTDocument has expired
DOCUMENT_NOT_SUPPORTEDDocument type is not accepted
FACE_MISMATCHFace verification failed
RESTRICTED_PERSONPerson appears on restricted lists
INVALID_DATASubmitted data contains errors
INCOMPLETE_SUBMISSIONRequired information is missing
COMPLIANCE_SCREENING_FAILEDCompliance screening failed during KYC
SCREENSHOTSSelfie does not match document photo (SumSub)
ℹ️

For the complete list of rejection labels, see the SumSub documentation on receiving and interpreting results.


Notification Scenarios

The following payload examples illustrate each event variant the integrator should expect to handle.

Scenario: Individual Requirement Rejected

Emitted when a single requirement within the entity's KYC submission fails verification. The presence of requirementId and slug identifies the specific requirement.

{
  "eventType": "account_status_change",
  "eventName": "card_issuance_api_access_updated",
  "data": {
    "message": "Card Issuance KYC API requirement rejected",
    "entityId": "ent_123e4567-e89b-12d3-a456-426614174000",
    "status": "REJECTED",
    "moderationComment": "Identity document image quality is insufficient. Please resubmit with clearer images",
    "reviewRejectType": "RETRY",
    "rejectLabels": ["DOCUMENT_QUALITY"],
    "requirementId": "req_456e7890-f12c-34d5-b678-901234567890",
    "slug": "individual-verification-identity",
    "timestamp": "2024-03-20T10:00:00Z"
  }
}

Scenario: Access Granted (Auto-Enabled)

Emitted when the entity meets all requirements and feature access is granted automatically without manual compliance review.

{
  "eventType": "account_status_change",
  "eventName": "card_issuance_api_access_updated",
  "data": {
    "message": "Card Issuance KYC API access auto-granted - Card Issuance KYC API",
    "entityId": "ent_123e4567-e89b-12d3-a456-426614174000",
    "status": "APPROVED",
    "timestamp": "2024-03-20T10:00:00Z"
  }
}

Scenario: Access Granted (Manual Approval)

Emitted when the compliance team manually approves access after reviewing the entity's submission. The moderationComment typically records the reviewer's rationale.

{
  "eventType": "account_status_change",
  "eventName": "card_issuance_api_access_updated",
  "data": {
    "message": "Card Issuance KYC API access granted",
    "entityId": "ent_123e4567-e89b-12d3-a456-426614174000",
    "status": "APPROVED",
    "moderationComment": "Identity verification and business documents approved by compliance team",
    "timestamp": "2024-03-20T10:00:00Z"
  }
}

Scenario: Access Revoked — Final Rejection

Emitted when overall feature access is revoked with no further attempts allowed. The integrator should disable card issuance functionality and direct the user to support.

{
  "eventType": "account_status_change",
  "eventName": "card_issuance_api_access_updated",
  "data": {
    "message": "Card Issuance KYC API access revoked",
    "entityId": "ent_123e4567-e89b-12d3-a456-426614174000",
    "status": "REJECTED",
    "moderationComment": "Business registration documents do not meet compliance standards",
    "reviewRejectType": "FINAL",
    "rejectLabels": ["DOCUMENT_NOT_SUPPORTED", "INVALID_DATA"],
    "timestamp": "2024-03-20T10:00:00Z"
  }
}

Scenario: Access Revoked — Retry Allowed

Emitted when overall feature access is revoked but the entity is permitted to resubmit corrected documentation. The integrator should disable card issuance functionality and prompt the user to resubmit.

{
  "eventType": "account_status_change",
  "eventName": "card_issuance_api_access_updated",
  "data": {
    "message": "Card Issuance KYC API access revoked",
    "entityId": "ent_123e4567-e89b-12d3-a456-426614174000",
    "status": "REJECTED",
    "moderationComment": "Identity document image quality is insufficient. Please resubmit with clearer images",
    "reviewRejectType": "RETRY",
    "rejectLabels": ["DOCUMENT_QUALITY"],
    "timestamp": "2024-03-20T10:00:00Z"
  }
}

Webhook Details

KYCaaS

KYCaaS verifies a single Card Issuance KYC requirement in one submission that results in either access granted or rejected.


Approved Flow

Verification submitted

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "b610f044-6a99-4803-84c0-78ea79912929",
    "message": "Card Issuance KYC API requirement pending",
    "entityId": "",
    "status": "PENDING",
    "rejectLabels": [],
    "timestamp": "2026-05-14T13:32:20.636Z"
  }
}

Access granted

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "bbd2441d-5adb-4eef-a6fe-545307b2a1a1",
    "message": "Card Issuance KYC API access granted",
    "entityId": "",
    "status": "APPROVED",
    "timestamp": "2026-05-14T13:45:01.000Z"
  }
}

Rejected Flow

The flow begins with the same PENDING webhooks as the approved flow, one for each requirement under review. It then diverges with a REJECTED webhook instead of an APPROVED one, and no APPROVED notification follows.

Verification rejected

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "542a1573-bba2-4fdf-b639-d379dbd2f9b2",
    "message": "Card Issuance KYC API requirement rejected",
    "entityId": "",
    "status": "REJECTED",
    "rejectLabels": ["COMPLIANCE_SCREENING_FAILED"],
    "moderationComment": "We are unable to provide services to you at this time. If you believe this is an error, please contact support.",
    "reviewRejectType": "FINAL",
    "timestamp": "2026-05-14T13:45:00.000Z"
  }
}

SUMSUB Related Errors (TBA)

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "542a1573-bba2-4fdf-b639-d379dbd2f9b2",
    "message": "Card Issuance KYC API requirement rejected",
    "entityId": "",
    "rejectLabels": ["SCREENSHOTS"],
    "reviewRejectType": "RETRY",
    "moderationComment": "Your selfie does not match your document photo. Please retake.",
    "reviewRejectType": "RETRY",
    "timestamp": "2026-05-14T13:45:00.000Z"
  }
}

Universal KYC

Universal KYC verifies multiple requirements with steps 1 and 2 repeating for each one before access is granted.


Approved Flow

Requirement submitted

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "b610f044-6a99-4803-84c0-78ea79912929",
    "message": "Universal KYC requirement pending",
    "entityId": "",
    "status": "PENDING",
    "rejectLabels": [],
    "timestamp": "2026-05-15T04:00:00.000Z"
  }
}

Access granted

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "30f138e1-0941-41a7-ac42-8e2d1b222a55",
    "message": "User profile approved - card generation enabled",
    "entityId": "",
    "status": "APPROVED",
    "timestamp": "2026-05-15T04:14:57.000Z"
  }
}

Rejected Flow

The flow begins with the same PENDING webhooks as the approved flow, one for each requirement under review. It then diverges with a REJECTED webhook instead of an APPROVED one, and no APPROVED notification follows.

Requirement rejected

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "542a1573-bba2-4fdf-b639-d379dbd2f9b2",
    "message": "Universal KYC requirement rejected",
    "entityId": "",
    "status": "REJECTED",
    "rejectLabels": ["COMPLIANCE_SCREENING_FAILED"],
    "moderationComment": "We are unable to provide services to you at this time. If you believe this is an error, please contact support.",
    "reviewRejectType": "FINAL",
    "timestamp": "2026-05-15T04:14:57.000Z"
  }
}

Payload Fields

FieldTypePresent whenDescription
eventNamestringalwaysAlways card_issuance_api_access_updated
eventTypestringalwaysAlways account_status_change
data.eventIduuidalwaysUnique ID for this notification — use for deduplication
data.messagestringalwaysHuman-readable description of the event
data.entityIduuidalwaysThe entity this notification relates to
data.statusstringalwaysPENDING, APPROVED, or REJECTED
data.timestampISO 8601alwaysWhen the event occurred
data.rejectLabelsstring[]verification eventsEmpty array [] when not rejected
data.moderationCommentstringREJECTED onlyReason provided by the compliance team
data.reviewRejectTypestringREJECTED onlyFINAL — cannot be retried. RETRY — user may resubmit

Webhook Handler Implementation

The following Express.js handler demonstrates a complete consumer implementation. It verifies the request signature, branches on the status enum value, and distinguishes individual requirement rejections from feature access revocations using the presence of requirementId and slug.

// Express.js webhook handler
app.post('/webhooks/reap', (req, res) => {
  const notification = req.body;
 
  // Verify webhook signature (see https://reap-ra.readme.io/docs/webhook-setup for implementation)
  if (!verifyWebhookSignature(req.body, req.headers['reap-signature'])) {
    return res.status(401).send('Invalid signature');
  }
 
  if (notification.eventName === 'card_issuance_api_access_updated') {
    const {
      entityId,
      status,
      moderationComment,
      reviewRejectType,
      rejectLabels,
      requirementId,
      slug,
    } = notification.data;
 
    // Handle status-based notifications using RequirementStatus enum values
    // Status is always present and uses enum values: APPROVED, PENDING, REJECTED
    switch (status) {
      case 'APPROVED':
        console.log(`✅ Entity ${entityId} now has Card Issuance KYC API access`);
        if (moderationComment) {
          console.log(`Compliance comment: ${moderationComment}`);
        }
        enableCardIssuanceFeatures(entityId);
        break;
 
      case 'PENDING':
        console.log(`⏳ Entity ${entityId} KYC is under review`);
        if (moderationComment) {
          console.log(`Compliance comment: ${moderationComment}`);
        }
        showPendingStatus(entityId, moderationComment);
        break;
 
      case 'REJECTED':
        // Check if this is a requirement rejection or feature access revocation
        if (requirementId && slug) {
          // Individual requirement rejected - user needs to fix specific issue
          console.log(`❌ Entity ${entityId} requirement '${slug}' was rejected`);
          if (moderationComment) {
            console.log(`Compliance comment: ${moderationComment}`);
          }
 
          if (rejectLabels && rejectLabels.length > 0) {
            console.log(`Rejection reasons: ${rejectLabels.join(', ')}`);
          }
 
          if (reviewRejectType === 'RETRY') {
            console.log(`💡 You can resubmit your documents after addressing the issues`);
            showRequirementRetryOption(entityId, slug, moderationComment, rejectLabels);
          } else if (reviewRejectType === 'FINAL') {
            console.log(`🚫 This is a final rejection. Please contact support for assistance`);
            showSupportContact(entityId);
          }
        } else {
          // Feature access revoked - entire access removed
          console.log(`❌ Entity ${entityId} Card Issuance KYC API access was revoked`);
          if (moderationComment) {
            console.log(`Compliance comment: ${moderationComment}`);
          }
          disableCardIssuanceFeatures(entityId);
        }
        break;
    }
  }
 
  res.status(200).send('OK');
});
 
// Helper functions (implement according to your application needs)
function enableCardIssuanceFeatures(entityId) {
  // Enable card issuance functionality for this entity
  // Update your application state, enable UI features, etc.
}
 
function disableCardIssuanceFeatures(entityId) {
  // Disable card issuance functionality for this entity
  // Update your application state, disable UI features, etc.
}
 
function showPendingStatus(entityId, comment) {
  // Show pending status to user with optional comment
}
 
function showRequirementRetryOption(entityId, requirementSlug, comment, rejectLabels) {
  // Show retry option for specific requirement with guidance based on rejection reasons
  // Focus user on fixing the specific requirement that was rejected
}
 
function showSupportContact(entityId) {
  // Show support contact information for final rejections
}

Integration Notes

Entity-Level Focus

This notification system focuses on entity-level compliance. Each entity represents either an individual or business customer requiring verification.

Automatic Feature Enablement

The system includes automatic feature enablement for qualifying entities. When an entity meets all requirements, they may receive access automatically without manual approval.

Smart Notification System

The notification system automatically determines the appropriate message and event details based on the compliance context, reducing the complexity of webhook handling.

Webhook Security

Always verify webhook signatures before processing notifications. See WEBHOOK_SETUP.md for detailed security implementation guidance.


Related Resources

ResourcePurpose
WEBHOOK_SETUP.mdWebhook subscription registration, lifecycle management, and signature verification
SumSub Rejection Labels ReferenceComplete list of rejection labels that may appear in rejectLabels

TL;DR

  • The card_issuance_api_access_updated event has eventType account_status_change and is emitted only for the KYCaaS and Universal KYC verification methods
  • data.status is always present and uses the RequirementStatus enum values APPROVED, PENDING, or REJECTED — branch on this field first
  • The presence of requirementId and slug distinguishes an individual requirement rejection from a feature access revocation
  • reviewRejectType distinguishes RETRY (resubmission allowed) from FINAL (contact support) for rejected events
  • rejectLabels provides the machine-readable reasons for rejection — see the SumSub reference for the complete list
  • Individual requirement approvals are not notified — notifications are only emitted on rejections and on overall feature access changes
  • Always verify the webhook signature before processing the payload as described in WEBHOOK_SETUP.md

Support

📘

Contact your Reap Implementation Manager for any questions about Card Issuance KYC API access notifications, including unexpected rejectLabels, status transitions, or final rejections. Include the entityId, the timestamp of the event, the environment (sandbox or production), and the full received payload when raising a support request.