KYC API Reference

Endpoints for managing and tracking customer verifications.

KYC API Reference

The KYC API allows you to programmatically create verification requests, track their statuses, and retrieve finalized reports.

All requests require the Authorization header with a valid API key.

[!TIP] Test the API Instantly: Fork our Melon Developer API Postman Collection to start sending test requests immediately.


Customers API

Manage the lifecycle of customer KYC records.

Create a Customer

Create a new customer profile and initiate the KYC field verification process.

POST /api/v1/customers

Required Scope: kyc:write

Request Body

{
  "firstName": "Babatunde",
  "lastName": "Ogunlesi",
  "phone": "+2348012345678",
  "email": "babatunde@example.com",
  "occupation": "Software Engineer",
  "bvn": "12345678901",
  "nin": "98765432101",
  "passportNumber": "A12345678",
  "loanId": "SYC-LOAN-98421",
  "loanType": "PERSONAL",
  "addresses": [
    {
      "label": "Home Address",
      "streetNumber": "15",
      "streetName": "Adeola Hopewell",
      "landmark": "Opposite Zenith Bank HQ",
      "city": "Victoria Island",
      "lga": "Eti-Osa",
      "state": "Lagos",
      "country": "Nigeria",
      "notes": "Ask for the brown duplex behind the security gate. Call customer 15 mins prior."
    }
  ],
  "documents": [
    {
      "fileName": "utility_bill.pdf",
      "fileUrl": "https://storage.sycamore.ng/docs/babatunde_utility_bill.pdf",
      "fileType": "application/pdf",
      "fileSize": 524288,
      "documentType": "UTILITY_BILL"
    },
    {
      "fileName": "national_id.jpg",
      "fileUrl": "https://storage.sycamore.ng/docs/babatunde_nin_card.jpg",
      "fileType": "image/jpeg",
      "fileSize": 1048576,
      "documentType": "ID_CARD"
    }
  ],
  "relogReason": "Optional reason if recreating a previously existing record"
}

Field Specifications & Enums

FieldTypeRequiredDescription
firstNamestringYesCustomer legal first name (2-50 chars).
lastNamestringYesCustomer legal last name (2-50 chars).
phonestringYesPrimary phone in E.164 Nigerian format (+234...).
emailstringNoCustomer email address.
occupationstringNoOccupation or employer title.
bvnstringNoBank Verification Number (11 digits).
ninstringNoNational Identification Number (11 digits).
passportNumberstringNoInternational Passport Number.
loanIdstringNoInternal loan reference ID for tracking.
loanTypestringNoPERSONAL, BUSINESS, DOCUMENT_VERIFICATION, or NEW_CUSTOMER.
addressesarrayNo1 to 5 customer physical verification addresses.
addresses[].notesstringNoInstructions for Field Agent (e.g. gate directions, building description).
documentsarrayNoSupporting verification documents (ID, utility bill, etc.).
documents[].documentTypestringYesID_CARD, UTILITY_BILL, PROOF_OF_ADDRESS, PASSPORT_PHOTO, BANK_STATEMENT, CAC_CERTIFICATE, or OTHER.

[!NOTE] Duplicate Handling Melon API checks for duplicates using phone, email, and loanId (first and last names are not considered unique). If a duplicate is found in the current environment, the API returns a 400 Bad Request.

  • If you simply need to update an existing customer, use PUT /api/v1/customers/:id.
  • If you intentionally need to re-log a customer (e.g. they applied again for a new loan), include the relogReason string in your request body to bypass the duplicate check.

Append Document to Customer

Append a supporting document to an existing customer record. Melon provides two flexible ways to attach files:

POST /api/v1/customers/:id/documents

Required Scope: kyc:write

Method A: Direct JSON (If already hosted on your storage)

Send a JSON payload with the public URL where your document is hosted:

{
  "fileName": "employment_letter.pdf",
  "fileUrl": "https://storage.sycamore.ng/docs/employment_letter.pdf",
  "fileType": "application/pdf",
  "fileSize": 245760,
  "documentType": "PROOF_OF_ADDRESS"
}

Method B: Multipart Upload (Melon-hosted Cloudinary storage)

Send a multipart/form-data request with the binary file. Melon will automatically optimize and upload the file to secure cloud storage:

curl -X POST "https://api.melon.ng/api/v1/customers/6659c1.../documents" \
  -H "Authorization: Bearer mk_live_..." \
  -F "file=@/path/to/utility_bill.pdf" \
  -F "documentType=UTILITY_BILL"

List Customers

Retrieve a paginated list of your customers.

GET /api/v1/customers

Required Scope: kyc:read

Query Parameters

  • page (optional): Page number (default: 1)
  • limit (optional): Items per page (default: 20)
  • status (optional): Filter by verification status (e.g., PENDING, VERIFIED, REJECTED)
  • search (optional): Search by name, email, or phone.

Get Customer Details

Retrieve the full details of a specific customer, including address details, agent field notes, photo evidence, supporting documents, and verification status.

GET /api/v1/customers/:id

Required Scope: kyc:read

Response Example

{
  "status": true,
  "message": "Customer details retrieved",
  "data": {
    "id": "6659c1b3f9...",
    "firstName": "Babatunde",
    "lastName": "Ogunlesi",
    "email": "babatunde@example.com",
    "phone": "+2348012345678",
    "status": "VERIFIED",
    "bvn": "***7890",
    "nin": "***2101",
    "passportNumber": "A12345678",
    "occupation": "Software Engineer",
    "loanId": "SYC-LOAN-98421",
    "loanType": "PERSONAL",
    "reportUrl": "https://api.melon.ng/api/v1/customers/6659c1b3f9.../report",
    "addresses": [
      {
        "label": "Home Address",
        "streetNumber": "15",
        "streetName": "Adeola Hopewell",
        "landmark": "Opposite Zenith Bank HQ",
        "city": "Victoria Island",
        "lga": "Eti-Osa",
        "state": "Lagos",
        "country": "Nigeria",
        "notes": "Ask for the brown duplex behind the security gate.",
        "status": "VERIFIED",
        "verificationData": {
          "verifiedAddress": "15 Adeola Hopewell, Victoria Island, Lagos",
          "verifiedAt": "2024-06-10T14:25:00.000Z",
          "verifiedLatitude": 6.4281,
          "verifiedLongitude": 3.4219,
          "agentNotes": "Met with customer's spouse at the address. Confirmed residency of 3+ years.",
          "verificationPhotos": [
            {
              "url": "https://res.cloudinary.com/melon/image/upload/v1.../building_exterior.jpg",
              "tag": "Building Exterior"
            },
            {
              "url": "https://res.cloudinary.com/melon/image/upload/v1.../street_sign.jpg",
              "tag": "Street Sign / Landmark"
            }
          ]
        }
      }
    ],
    "documents": [
      {
        "id": "6659c2a1...",
        "fileName": "utility_bill.pdf",
        "fileUrl": "https://storage.sycamore.ng/docs/babatunde_utility_bill.pdf",
        "fileType": "application/pdf",
        "fileSize": 524288,
        "documentType": "UTILITY_BILL",
        "uploadedAt": "2024-06-08T10:15:00.000Z",
        "verified": true
      }
    ],
    "verificationDate": "2024-06-10T14:30:00.000Z",
    "submittedAt": "2024-06-08T10:00:00.000Z",
    "createdAt": "2024-06-08T10:00:00.000Z",
    "updatedAt": "2024-06-10T14:30:00.000Z"
  }
}

Add Address

Append a new address to an existing customer for verification (Max 5 addresses per customer).

POST /api/v1/customers/:id/addresses

Required Scope: kyc:write

Request Body Example

{
  "label": "Office Address",
  "streetNumber": "19",
  "streetName": "Adeola Hopewell",
  "landmark": "Near Diamond Plaza",
  "city": "Victoria Island",
  "lga": "Eti-Osa",
  "state": "Lagos",
  "country": "Nigeria",
  "notes": "Reception is on the 2nd floor. Ask for Operations team."
}

Update Customer

Modify an existing customer's details.

PUT /api/v1/customers/:id

Required Scope: kyc:write


Delete Customer

Soft-delete a customer record from the active verification queue.

DELETE /api/v1/customers/:id

Required Scope: kyc:write


Download KYC Report

Download a verified customer's final KYC report as a formatted PDF document.

GET /api/v1/customers/:id/report

Required Scope: kyc:read


Verification API

Check and track the verification progress of your customers without fetching full customer profiles.

Get Verification Status

Check the current verification status for a specific customer. Returns detailed address verification outcomes, field agent notes, coordinates, photo evidence, and attached documents.

GET /api/v1/verification/:customerId/status

Required Scope: kyc:read

Response Example

{
  "status": true,
  "message": "Verification status retrieved",
  "data": {
    "customerId": "6659c1b3f9...",
    "customerName": "Babatunde Ogunlesi",
    "overallStatus": "VERIFIED",
    "loanId": "SYC-LOAN-98421",
    "loanType": "PERSONAL",
    "verificationDate": "2024-06-10T14:30:00.000Z",
    "addresses": [
      {
        "label": "Home Address",
        "status": "VERIFIED",
        "streetNumber": "15",
        "streetName": "Adeola Hopewell",
        "landmark": "Opposite Zenith Bank HQ",
        "city": "Victoria Island",
        "lga": "Eti-Osa",
        "state": "Lagos",
        "country": "Nigeria",
        "notes": "Ask for the brown duplex behind the security gate.",
        "verificationData": {
          "verifiedAddress": "15 Adeola Hopewell, Victoria Island, Lagos",
          "verifiedAt": "2024-06-10T14:25:00.000Z",
          "verifiedLatitude": 6.4281,
          "verifiedLongitude": 3.4219,
          "agentNotes": "Address confirmed. Customer met in person and verified utility bill.",
          "verificationPhotos": [
            {
              "url": "https://res.cloudinary.com/melon/image/upload/v1.../exterior.jpg",
              "tag": "Building Exterior"
            },
            {
              "url": "https://res.cloudinary.com/melon/image/upload/v1.../gate.jpg",
              "tag": "Compound Entrance"
            }
          ],
          "photoCount": 2
        }
      }
    ],
    "documents": [
      {
        "id": "6659c2a1...",
        "fileName": "utility_bill.pdf",
        "fileUrl": "https://storage.sycamore.ng/docs/babatunde_utility_bill.pdf",
        "fileType": "application/pdf",
        "fileSize": 524288,
        "documentType": "UTILITY_BILL",
        "uploadedAt": "2024-06-08T10:15:00.000Z",
        "verified": true
      }
    ]
  },
  "meta": {
    "requestId": "req_123abc456def",
    "timestamp": "2024-06-10T14:30:00.000Z"
  }
}

Get Verification Statistics

Get aggregate verification statistics for your organization. Useful for dashboard integrations.

GET /api/v1/verification/stats

Required Scope: kyc:read

Response Example

{
  "status": true,
  "message": "Verification statistics retrieved",
  "data": {
    "total": 1500,
    "pending": 200,
    "verified": 1250,
    "rejected": 50
  },
  "meta": {
    "requestId": "req_123abc456def",
    "timestamp": "2024-06-10T14:30:00.000Z"
  }
}

On this page