Appearance
API Keys
Manage API keys for programmatic access to the OVN Pay platform.
Overview
OVN Pay uses API keys to authenticate API requests. Each key has:
- A mode (sandbox or production)
- A set of scopes defining what actions it can perform
- An approval status (production keys require admin approval)
Key Modes
Sandbox Keys
- Prefix:
ovnp_sbox_ - Approval: Automatic (no approval required)
- Use case: Development, testing, integration work
- Data: Simulated responses, no real transactions
Sandbox keys are ideal for:
- Building and testing integrations
- Prototyping new features
- Learning the API
Production Keys
- Prefix:
ovnp_prod_ - Approval: Requires admin review and approval
- Use case: Live transactions, real payouts
- Data: Real money movement
Production keys require:
- A use case description explaining the intended purpose
- Admin approval before the key becomes active
Available Scopes
| Scope | Description |
|---|---|
drivers:read | View driver list and details |
drivers:write | Create and update drivers |
payouts:read | View payouts |
payouts:write | Create and cancel payouts |
batches:read | View payout batches |
batches:write | Create and release batches |
balance:read | View wallet balance |
webhooks:manage | Configure webhooks |
Managing API Keys
List Your Keys
http
GET /api/v1/developer/keys
Authorization: Bearer your_session_tokenResponse:
json
{
"success": true,
"keys": [
{
"id": "key_abc123",
"name": "Development Key",
"mode": "sandbox",
"prefix": "ovnp_sbox_",
"scopes": ["drivers:read", "payouts:read", "payouts:write"],
"approval_status": "approved",
"created_at": "2026-02-15T10:00:00Z",
"expires_at": null,
"last_used_at": "2026-02-18T14:30:00Z",
"is_usable": true
}
],
"meta": {
"requestId": "uuid",
"timestamp": "2026-02-18T15:00:00Z"
}
}Create a Sandbox Key
http
POST /api/v1/developer/keys
Authorization: Bearer your_session_token
Content-Type: application/json
{
"name": "Development Key",
"mode": "sandbox",
"scopes": ["drivers:read", "payouts:read", "payouts:write", "balance:read"]
}Response:
json
{
"success": true,
"id": "key_abc123",
"name": "Development Key",
"mode": "sandbox",
"prefix": "ovnp_sbox_",
"scopes": ["drivers:read", "payouts:read", "payouts:write", "balance:read"],
"approval_status": "approved",
"created_at": "2026-02-18T15:00:00Z",
"key": "ovnp_sbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"note": "Save this key now. It will not be shown again.",
"meta": {
"requestId": "uuid",
"timestamp": "2026-02-18T15:00:00Z"
}
}Create a Production Key
http
POST /api/v1/developer/keys
Authorization: Bearer your_session_token
Content-Type: application/json
{
"name": "Production Integration Key",
"mode": "production",
"scopes": ["drivers:read", "payouts:read", "payouts:write", "balance:read"],
"approval_reason": "This key will be used for our ERP integration to automate weekly driver payouts from our dispatch system."
}Response:
json
{
"success": true,
"id": "key_xyz789",
"name": "Production Integration Key",
"mode": "production",
"prefix": "ovnp_prod_",
"scopes": ["drivers:read", "payouts:read", "payouts:write", "balance:read"],
"approval_status": "pending",
"created_at": "2026-02-18T15:00:00Z",
"key": null,
"note": "Production key pending admin approval. You will be notified when approved.",
"meta": {
"requestId": "uuid",
"timestamp": "2026-02-18T15:00:00Z"
}
}Get Key Details
http
GET /api/v1/developer/keys/:id
Authorization: Bearer your_session_tokenResponse:
json
{
"success": true,
"id": "key_abc123",
"name": "Development Key",
"mode": "sandbox",
"prefix": "ovnp_sbox_",
"scopes": ["drivers:read", "payouts:read"],
"approval_status": "approved",
"approval_reason": null,
"created_at": "2026-02-15T10:00:00Z",
"expires_at": null,
"last_used_at": "2026-02-18T14:30:00Z",
"is_usable": true,
"usability_reason": null,
"approved_by": null,
"approved_at": null,
"meta": {
"requestId": "uuid",
"timestamp": "2026-02-18T15:00:00Z"
}
}Revoke a Key
http
DELETE /api/v1/developer/keys/:id
Authorization: Bearer your_session_tokenResponse:
json
{
"success": true,
"message": "API key revoked successfully",
"meta": {
"requestId": "uuid",
"timestamp": "2026-02-18T15:00:00Z"
}
}Regenerate a Key
Creates a new key with the same properties as the original. The old key is immediately revoked.
http
POST /api/v1/developer/keys/:id/regenerate
Authorization: Bearer your_session_tokenResponse:
json
{
"success": true,
"id": "key_new456",
"name": "Development Key",
"mode": "sandbox",
"prefix": "ovnp_sbox_",
"scopes": ["drivers:read", "payouts:read"],
"approval_status": "approved",
"created_at": "2026-02-18T15:30:00Z",
"old_key_id": "key_abc123",
"key": "ovnp_sbox_newxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"note": "Save this key now. It will not be shown again.",
"meta": {
"requestId": "uuid",
"timestamp": "2026-02-18T15:30:00Z"
}
}Production Key Regeneration
When regenerating a production key, the new key requires admin approval again. Plan accordingly to avoid service interruptions.
List Available Scopes
http
GET /api/v1/developer/scopes
Authorization: Bearer your_session_tokenResponse:
json
{
"success": true,
"scopes": [
{ "name": "drivers:read", "description": "View driver list and details" },
{ "name": "drivers:write", "description": "Create and update drivers" },
{ "name": "payouts:read", "description": "View payouts" },
{ "name": "payouts:write", "description": "Create and cancel payouts" },
{ "name": "batches:read", "description": "View payout batches" },
{ "name": "batches:write", "description": "Create and release batches" },
{ "name": "balance:read", "description": "View wallet balance" },
{ "name": "webhooks:manage", "description": "Configure webhooks" }
],
"meta": {
"requestId": "uuid",
"timestamp": "2026-02-18T15:00:00Z"
}
}Using API Keys
Include your API key in the Authorization header:
http
GET /api/v1/payouts
Authorization: Bearer ovnp_sbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/jsonSecurity Best Practices
- Never share keys - Each integration should have its own key
- Use minimal scopes - Only request the permissions you need
- Rotate keys regularly - Regenerate keys periodically for security
- Revoke unused keys - Remove keys that are no longer needed
- Use sandbox for development - Never use production keys in dev environments
- Store keys securely - Use environment variables or secret management
- Never commit keys to git - Add API keys to
.gitignore
Approval Workflow
For Developers
- Create a production key with a clear use case description
- Key enters "pending" state
- Wait for admin approval notification
- Once approved, the full key is revealed once
- Save the key immediately - it won't be shown again
For Admins
Admins can manage API keys through the admin dashboard or via the Admin API:
Admin API Endpoints:
| Endpoint | Description |
|---|---|
GET /api/v1/admin/api-keys | List all API keys with filtering |
GET /api/v1/admin/api-keys/pending | List keys awaiting approval |
GET /api/v1/admin/api-keys/:id | Get key details |
POST /api/v1/admin/api-keys/:id/approve | Approve a production key |
POST /api/v1/admin/api-keys/:id/reject | Reject a production key |
DELETE /api/v1/admin/api-keys/:id | Revoke any key |
When approving, the full production key is revealed once and cannot be retrieved again.
Expiration
API keys can optionally be created with an expiration:
json
{
"name": "Temporary Integration Key",
"mode": "sandbox",
"scopes": ["payouts:read"],
"expires_in": 30
}The expires_in parameter specifies days until expiration (1-365 days). Expired keys return a 401 Unauthorized error.
Error Responses
| Code | Message |
|---|---|
UNAUTHORIZED | Authentication required |
INVALID_REQUEST | Missing or invalid parameters |
INVALID_SCOPES | One or more scopes are invalid |
KEY_NOT_FOUND | API key not found |
REVOKE_FAILED | Failed to revoke key |
SDK Usage
ts
import { PaystreamClient } from "@ovn/paystream-client";
const client = new PaystreamClient({
apiKey: process.env.OVNPAY_API_KEY!, // Your sandbox or production key
apiUrl: "https://api.ovnpays.com/api/v1",
});
// The SDK automatically includes your API key in all requests
const payouts = await client.payouts.list();