The KYC Genie API

Full programmatic control over your due diligence pipeline. Create entities, build and send KYC questionnaires, capture responses, run sanctions and PEP screening, and automate approve/reject decisions - all via REST API. Use your test environment while you build, then switch to live when you're ready to ship. Python SDK available now, with more languages on the way.

Make your first call

1. Get your API key

  1. Log in to your KYC Genie account.
  2. To use the test environment, click your profile in the top right and select Switch to Test. Your dashboard will switch to the test environment.
  3. Go to Settings → API Keys and create a new key. Keys created in the test environment never charge credits. Some features will be simulated and return mock data such as Screenings or Verifications, but you can build and test your integration end-to-end without worrying about costs or affecting real customers.
  4. When you're ready for production, switch back to your live environment and create a kycg_live_ key the same way.
Test and live are separate environments

All data is completely isolated between them. Build and verify everything in test before switching your key.

2. Install

Python 3.10 or higher required.

Install

pip install kycgenie

3. Set your key

Never hardcode API keys in source. Set it as an environment variable:

Environment variable

export API_KEY="kycg_test_your_key_here"

Not using Python? Switch to the cURL or JavaScript tabs on the right - the same pattern applies to any language or HTTP tool.

List your questionnaire templates

from kycgenie import KYCGenie

client = KYCGenie(api_key="YOUR_API_KEY")

result = client.questionnaire_templates.list()

for t in result.results:
    print(f"{t.name} ({t.uuid}) - {t.question_count} questions")
curl https://api.kycgenie.com/api/v1/questionnaires/ \
  -H "Authorization: Bearer $API_KEY"
const resp = await fetch(
  'https://api.kycgenie.com/api/v1/questionnaires/',
  {
    headers: {
      Authorization: 'Bearer YOUR_API_KEY'
    }
  }
);
const data = await resp.json();
data.results.forEach(t => console.log(t.id, t.name));

Response

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 55,
      "name": "Standard DDQ",
      "questionnaire_type": "ddq",
      "question_count": 42,
      "is_active": true
    }
  ]
}

Authentication error

{
  "detail": "Authentication credentials were not provided."
}

HTTP 401. Check that your key is set correctly and that you're using the right environment's key.

Errors

Every error response from the API uses the same envelope, regardless of the endpoint. Check the HTTP status code first, then use code to branch in your code.

FieldTypeDescription
error string Human-readable summary of what went wrong.
code string Machine-readable error code - safe to switch on.
request_id string Include this when contacting support to correlate logs.
errors object Field-level validation messages, keyed by field name. Only present on validation_error.
details object Extra context to help you act on the error - e.g. the conflicting resource ID on a 409, or the current status on an invalid state transition. Shape varies by error; present when there is actionable context beyond error and code.
HTTP statuscodeMeaning
400validation_errorRequest body failed validation - check errors.
400invalid_requestRequest is structurally valid but logically invalid (e.g. wrong state, unsupported operation) - check details.
401authentication_failedMissing or invalid API key.
402insufficient_creditsYour account has no remaining credits.
403permission_deniedYour key doesn't have access to this resource.
404not_foundResource doesn't exist or isn't accessible to your tenant.
409conflictAction conflicts with current state - check details.
409idempotency_conflictSame Idempotency-Key reused with a different request body.
429rate_limitedToo many requests - back off and retry.
500server_errorSomething went wrong on our end.
502upstream_errorAn external service (e.g. a webhook endpoint) returned an error or was unreachable - check details.

Authentication error (401)

{
  "error": "Authentication credentials were not provided.",
  "code": "authentication_failed",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

Validation error (400)

{
  "error": "Validation failed.",
  "code": "validation_error",
  "request_id": "550e8400-e29b-41d4-a716-446655440001",
  "errors": {
    "legal_name": ["This field is required."],
    "entity_type": ["Must be 'company' or 'individual'."]
  }
}

Invalid request (400) - with details

{
  "error": "This response has already been submitted and cannot be modified.",
  "code": "invalid_request",
  "request_id": "550e8400-e29b-41d4-a716-446655440003",
  "details": {
    "current_status": "submitted"
  }
}

Conflict error (409)

{
  "error": "A check is already in progress.",
  "code": "conflict",
  "request_id": "550e8400-e29b-41d4-a716-446655440002",
  "details": {
    "existing_check_id": "d67177bf-6871-45bf-85f2-95a1e52ccc64",
    "status": "pending"
  }
}