API Reference
The Pay Engineers Compliance API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.
You can use the API in sandbox without affecting live data. The API key you use to authenticate the request determines whether the request runs in sandbox or production.
Credentials are issued per compliance request and per environment, and published in your compliance portal once your request is validated.
Local development — endpoints resolve to https://payengineers.com//api/v1
Just getting started?
Submit a compliance request to receive your sandbox credentials, then verify them with your first call.
Base URL
https://payengineers.com/api/v1
Tooling
By default the examples use curl to interact with the API over HTTP. Import the OpenAPI spec to generate a client in your language.
Base URLs
Each environment has a dedicated API host. Use sandbox while building, staging for pre-production checks, and production only after your compliance request is validated and credentials are published.
| Environment | Versioned API |
|---|---|
| Sandbox | https://payengineers.com/api/v1 |
| Staging | https://payengineers.com/api/v1 |
| Production | https://payengineers.com/api/v1 |
Environment hosts
Sandbox https://payengineers.com/api
Staging https://payengineers.com/api
Production https://payengineers.com/api
Authentication
The API uses API keys to authenticate requests. You can view and manage your keys in the compliance portal once they are published for your request.
Sandbox keys start with pe_test_ and have unrestricted access to your sandbox. Send your key as an Authorization: Bearer header, and include your merchant identifier when available.
Your API keys carry many privileges — keep them secure. Do not share them in publicly accessible places such as GitHub or client-side code. Use GET /credentials/verify to confirm your key is active before going live.
Authenticated request
curl https://payengineers.com/api/v1/credentials/verify \
-H "Authorization: Bearer $PAY_ENGINEERS_SANDBOX_API_KEY" \
-H "X-Merchant-Id: $PAY_ENGINEERS_SANDBOX_MERCHANT_ID"
# The colon prevents curl from asking for a password.
Required headers
Authorization: Bearer <PAY_ENGINEERS_SANDBOX_API_KEY>
X-Merchant-Id: <PAY_ENGINEERS_SANDBOX_MERCHANT_ID>
Accept: application/json
Headers
Attributes
- Authorization required
- Required on protected routes. Bearer token from your published API key or access token.
- X-Merchant-Id recommended
- Must match the merchant identifier published for the same environment.
- X-Pay-Engineers-Signature webhooks only
- Present on inbound webhooks. Verify it using your webhook signing secret.
Example headers
GET /v1/merchant HTTP/1.1
Host: payengineers.com/api
Authorization: Bearer pe_test_51Tt17r...X400fxV8FBwU
X-Merchant-Id: pe_test_merchant_84fd
Accept: application/json
Errors
Pay Engineers uses conventional HTTP response codes to indicate the success or failure of an API request. Codes in the 2xx range indicate success, codes in the 4xx range indicate an error with the information provided, and codes in the 5xx range indicate a problem on our side.
Attributes
- code string
- A short string identifying the error programmatically, e.g.
credential_expired. - message string
- A human-readable message providing more details about the error.
- errors nullable object
- On validation errors, a map of field names to the failed rules.
HTTP status code summary
| 200 | OK | Everything worked as expected. |
| 401 | Unauthorized | No valid API key provided, or credential expired. |
| 403 | Forbidden | IP not allowlisted or merchant mismatch. |
| 404 | Not Found | The requested resource doesn't exist. |
| 422 | Validation | Invalid request body on POST endpoints. |
| 429 | Too Many Requests | Rate limit hit — use exponential backoff. |
| 5xx | Server Errors | Something went wrong on our end. (These are rare.) |
Error response
{
"code": "validation_error",
"message": "The amount field is required.",
"errors": {
"amount": ["The amount field is required."]
}
}
Health
Public liveness probe. No authentication required — use it for connectivity checks and uptime monitoring.
Request
curl -s "https://payengineers.com/api/v1/health"
Response
{
"status": "ok",
"service": "pay-engineers-compliance-api",
"version": "v1",
"environment": "sandbox",
"timestamp": "2026-07-16T12:00:00+00:00"
}
Credentials
Validates the bearer token and returns the merchant context, scopes and expiry. This is the ideal first call after copying credentials from the portal.
Request
curl -s "https://payengineers.com/api/v1/credentials/verify" \
-H "Authorization: Bearer $PAY_ENGINEERS_SANDBOX_API_KEY" \
-H "X-Merchant-Id: $PAY_ENGINEERS_SANDBOX_MERCHANT_ID"
Merchant
Returns the merchant identifier and processor context linked to the authenticated credential.
Request
curl -s "https://payengineers.com/api/v1/merchant" \
-H "Authorization: Bearer $PAY_ENGINEERS_SANDBOX_API_KEY" \
-H "X-Merchant-Id: $PAY_ENGINEERS_SANDBOX_MERCHANT_ID"
Payments
List or create payments in the authenticated environment. Sandbox returns succeeded immediately for test flows.
Body parameters
- amount integer, required
- Amount in the smallest currency unit (e.g. cents).
- currency string, required
- Three-letter ISO currency code, e.g.
EUR. - description string, optional
- Free-text description shown in reports and receipts.
List payments
curl -s "https://payengineers.com/api/v1/payments" \
-H "Authorization: Bearer $PAY_ENGINEERS_SANDBOX_API_KEY" \
-H "X-Merchant-Id: $PAY_ENGINEERS_SANDBOX_MERCHANT_ID"
Create payment
curl -s -X POST "https://payengineers.com/api/v1/payments" \
-H "Authorization: Bearer $PAY_ENGINEERS_SANDBOX_API_KEY" \
-H "X-Merchant-Id: $PAY_ENGINEERS_SANDBOX_MERCHANT_ID" \
-H "Content-Type: application/json" \
-d '{"amount":1000,"currency":"EUR","description":"Test payment"}'
Webhooks
Returns a signed sample webhook payload so you can test signature verification before receiving live events.
Replay protection (recommended)
- Read
X-Pay-Engineers-Timestamp. - Reject if older than 5 minutes.
- Compute the HMAC on
timestamp + "." + raw_body. - Compare using
hash_equals().
Verification algorithm
$expected = hash_hmac(
'sha256',
$rawRequestBody,
getenv('PAY_ENGINEERS_SANDBOX_WEBHOOK_SECRET')
);
$valid = hash_equals($expected, $_SERVER['HTTP_X_PAY_ENGINEERS_SIGNATURE']);
Request a sample
curl -s -X POST "https://payengineers.com/api/v1/webhooks/sample" \
-H "Authorization: Bearer $PAY_ENGINEERS_SANDBOX_API_KEY"
API Explorer
Run real requests against sandbox from this page. Use a published sandbox key from your compliance request — no code required.
Response
OpenAPI, Swagger and Postman
Use machine-readable specifications for CI pipelines, client generation and QA automation.
Generate a client
# Example with openapi-generator
openapi-generator generate \
-i https://payengineers.com/ar/authorizations-compliance/docs/openapi.json \
-g php \
-o ./pay-engineers-client
Rate limits and retries
The default API rate limit is 60 requests per minute per API key or client IP. When you receive a 429, back off exponentially and keep the same reference / idempotency key when retrying POST /payments.
- Exponential backoff: 1s, 2s, 4s, 8s.
- Maximum 5 retries.
- Never retry with a different idempotency key.
Rate limit headers
Retry-After: 60
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 12
Configuration
Store credentials in environment variables. Download a ready-made .env pack from your compliance request once parameters are published.
Available scopes
.env
PAY_ENGINEERS_SANDBOX_API_KEY=pe_test_...
PAY_ENGINEERS_SANDBOX_MERCHANT_ID=pe_test_...
PAY_ENGINEERS_SANDBOX_BASE_URL=https://payengineers.com/api
PAY_ENGINEERS_SANDBOX_API_URL=https://payengineers.com/api/v1
PAY_ENGINEERS_SANDBOX_WEBHOOK_SECRET=whsec_test_...
PAY_ENGINEERS_API_VERSION=v1
CDN & JavaScript SDK
Load the lightweight SDK from our CDN. In production it is served from cdn.payengineers.com.
CDN base: https://payengineers.com/cdn
Browser integration
<script src="https://payengineers.com/cdn/compliance/v1/pay-engineers-sdk.js"></script>
<script>
const client = PayEngineers.createClient({
apiKey: '...',
merchantId: '...',
baseUrl: 'https://payengineers.com/api/v1',
environment: 'sandbox',
});
client.health().then(console.log);
</script>
Examples
Copy-paste snippets for the most common stacks. Both examples list payments in sandbox using environment variables for credentials.
List payments
$ch = curl_init('https://payengineers.com/api/v1/payments');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAY_ENGINEERS_SANDBOX_API_KEY'),
'X-Merchant-Id: ' . getenv('PAY_ENGINEERS_SANDBOX_MERCHANT_ID'),
'Accept: application/json',
],
]);
echo curl_exec($ch);
List payments
const res = await fetch('https://payengineers.com/api/v1/payments', {
headers: {
Authorization: `Bearer ${process.env.PAY_ENGINEERS_SANDBOX_API_KEY}`,
'X-Merchant-Id': process.env.PAY_ENGINEERS_SANDBOX_MERCHANT_ID,
Accept: 'application/json',
},
});
console.log(await res.json());
Changelog and versioning
v1.2.0 — 2026-07-16
Added OpenAPI and Postman exports, API Explorer and webhook replay guidance.
v1.1.0 — 2026-07-10
Introduced /webhooks/sample and the credential verify endpoint.
Versioning rules
- Breaking changes are released only on new major versions.
- v1 endpoints remain stable for at least 12 months after a deprecation notice.
- Deprecation notices are published in the docs and in response headers.
Go-live checklist
Work through both lists before switching production traffic to your integration.
Pre-production
- Sandbox pack published (API key, merchant ID, endpoint, webhook secret).
- At least one connection test passed.
- Webhook signature verification implemented.
- Rate limit handling and retries tested.
Production launch
- Switch to the production base URL and production credentials.
- Restrict credentials using allowlisted IPs.
- Enable monitoring on /health and critical flows.
- Plan credential rotation every 90 days.
Language guides
Additional tutorials published by Pay Engineers.
php
PHP cURL quickstart
A minimal, dependency-free PHP example for calling a published sandbox endpoint with an API key, plus guidance on authentication headers, error handling, environment variables and secret rotation.
laravel
Laravel HTTP client guide
How to consume published compliance credentials from a Laravel application using the HTTP facade, including config binding, retry/backoff strategy, error handling and safe secret storage.
nodejs
Node.js fetch sample
A Node.js example using the native fetch API to authenticate against a sandbox endpoint, covering environment configuration, timeout handling, retries and safe logging of processor responses.
java
Java HttpClient sample
A Java 11+ example built on the standard library HttpClient, showing authentication, timeout configuration, response handling and where to store processor credentials in a typical Spring application.
python
Python requests sample
A Python example using the requests library to call a sandbox endpoint securely, with guidance on environment variables, session reuse, timeouts, retries and structured error handling.
dotnet
.NET HttpClient sample
A .NET example showing how to consume sandbox and production endpoints from ASP.NET or a console application, including dependency injection, typed clients, Polly retry policies and secret configuration.