Skip to main content

Overview

Every API request must include three headers:

x-api-key

Your API key ID only (format: ak_live_xxx)

x-timestamp

Current Unix timestamp in milliseconds

x-signature

HMAC-SHA256 signature of the request
The x-api-key header should contain ONLY the key ID, NOT the full API key. The secret key is never transmitted over the wire.

Getting Your API Key

1

Log in to your CeyPay dashboard

2

Navigate to Settings > API Keys

3

Click Generate API Key

4

Copy the complete API key (you'll only see it once!)

5

Store it securely (treat it like a password)

API Key Format: ak_live_abc123.sk_live_xyz789
  • First part (ak_live_abc123): Public key ID - sent in x-api-key header
  • Second part (sk_live_xyz789): Secret key - used locally to derive signing key, NEVER transmitted

Signature Calculation

The signature is calculated using a derived signing key (hash of your secret):

Why Use a Derived Key?

This design ensures your secret key is never transmitted over the network:
  • You send only the key ID in x-api-key
  • The signature proves you possess the secret without revealing it
  • Even if an attacker intercepts the request, they cannot forge new requests

Components:

  1. signingKey: SHA256 hash of your secret key (computed locally)
  2. timestamp: Unix timestamp in milliseconds (same value as x-timestamp header)
  3. method: HTTP method in UPPERCASE (GET, POST, PATCH, DELETE)
  4. path: Full request path including query parameters (e.g., /v1/payments?page=1)
  5. body: Request body as JSON string (empty string for GET/DELETE requests)

Implementation Examples

Common Mistakes & Troubleshooting

1. Sending Full API Key in Header

Wrong: Sending the full key including secret
Correct: Send only the key ID

2. Using Raw Secret Instead of Derived Key

Wrong: Signing with raw secret
Correct: Sign with derived key (SHA256 hash of secret)

3. Incorrect Timestamp Format

Wrong: Using seconds instead of milliseconds
Correct: Use milliseconds

4. Incorrect Message Concatenation

Wrong: Adding spaces or separators
Correct: Direct concatenation with no separators

5. Query Parameters in Path

For GET requests with query parameters, include them in the path: Correct:

6. JSON Body Formatting

Ensure the body is stringified exactly as sent in the request: Correct:

7. Timestamp Expiration

Timestamps are valid for 5 minutes. If you get a timestamp error:
  • Ensure your server’s clock is synchronized (use NTP)
  • Generate the timestamp immediately before making the request
  • Don’t reuse old timestamps

Security Best Practices

  1. Never expose your secret key
    • Don’t commit it to version control
    • Use environment variables
    • Rotate keys if compromised
  2. Use HTTPS only
    • Never send API requests over HTTP
    • Validate SSL certificates
  3. Implement timestamp validation
    • Reject requests with timestamps older than 5 minutes
    • Prevents replay attacks
  4. Log signature failures
    • Monitor for unusual patterns
    • Could indicate attempted attacks
  5. Rotate API keys periodically
    • Recommended: Every 90 days
    • Immediately if compromised
  6. Store the derived signing key securely
    • Compute it once at application startup
    • Keep it in memory, don’t log it

Testing Your Implementation

Use the webhook test endpoint to verify your signature calculation:
If you get a 401 Unauthorized, check:
  1. x-api-key contains ONLY the key ID (no .sk_live_... part)
  2. Signing key is SHA256 hash of your secret
  3. Timestamp is current (within 5 minutes) and in milliseconds
  4. Signature calculation matches exactly
  5. HTTP method is uppercase
  6. Path includes query parameters if any

Error Responses

401 Unauthorized - Invalid x-api-key Format

Fix: Send only the key ID in x-api-key, not the full keyId.secret format.

401 Unauthorized - Invalid Signature

Fix: Ensure you’re using the derived signing key (SHA256 hash of secret) for HMAC.

401 Unauthorized - Timestamp Outside Valid Window

Fix: Ensure timestamp is current (within 5 minutes) and in milliseconds.

401 Unauthorized - Invalid API Key

Fix: Verify your API key ID is correct and hasn’t been revoked.

Rate Limits

API requests are rate-limited per endpoint. See rate-limits.md for details. Rate limit headers are included in every response:

Need Help?

Quick Start Guide

Get started with your first payment in minutes

Error Codes

Understand and troubleshoot API errors

Contact Support

Reach out to our team for assistance