API reference
Webhooks
Endpoints that receive signed events, and the event log behind them.
List webhook endpoints
GET/v1/webhook_endpoints
Returns a page of WebhookEndpoint objects.
Query parameters
limitintegerDefault
10.starting_afterstringCursor; an object ID. Returns the page after it. Cannot be combined with
ending_before.ending_beforestringCursor; an object ID. Returns the page before it. Cannot be combined with
starting_after.
Responses
- 200A page of endpoints.
- 401The API key is missing, invalid or revoked.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl "https://sandbox.api.ndeipi.example/v1/webhook_endpoints" \
-H "Api-Key: $NDEIPI_API_KEY"{
"data": [
{
"id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V",
"object": "webhook_endpoint",
"url": "https://api.yourapp.example/ndeipi/webhooks",
"status": "enabled",
"event_types": [
"transfer.state_changed",
"user.kyc_status_changed"
],
"description": "Production receiver",
"public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAEu+SJIWlScv5fJmnV1iNNpGw345qGqFu0DJR6GdDIaA=\n-----END PUBLIC KEY-----\n",
"version": 2,
"created_at": "2026-10-16T09:30:00Z"
}
],
"has_more": false
}Register a webhook endpoint
POST/v1/webhook_endpoints
Registers an HTTPS URL and generates an Ed25519 key pair for it. The public key is returned in public_key_pem; the private key never leaves the server. New endpoints start disabled and are enabled by a successful test delivery or an update.
Returns WebhookEndpoint.
Headers
Idempotency-KeyheaderrequiredA unique key for this write, up to 255 characters. Send the same key to retry safely; see idempotency.
Body
urlstringrequiredevent_typesarray of stringTypes to deliver. Omit or leave empty for all types.
descriptionstring
Responses
- 201Endpoint registered.
- 400The request is malformed.
- 401The API key is missing, invalid or revoked.
- 422The request is well formed but fails validation or a business rule.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl -X POST "https://sandbox.api.ndeipi.example/v1/webhook_endpoints" \
-H "Api-Key: $NDEIPI_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.yourapp.example/ndeipi/webhooks",
"event_types": [
"transfer.state_changed",
"user.kyc_status_changed"
],
"description": "Production receiver"
}'{
"id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V",
"object": "webhook_endpoint",
"url": "https://api.yourapp.example/ndeipi/webhooks",
"status": "disabled",
"event_types": [
"transfer.state_changed",
"user.kyc_status_changed"
],
"description": "Production receiver",
"public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAEu+SJIWlScv5fJmnV1iNNpGw345qGqFu0DJR6GdDIaA=\n-----END PUBLIC KEY-----\n",
"version": 1,
"created_at": "2026-10-16T09:30:00Z"
}Get a webhook endpoint
GET/v1/webhook_endpoints/{webhook_endpoint_id}
Returns WebhookEndpoint.
Path parameters
webhook_endpoint_idstringrequiredStarts with
we_.
Responses
- 200The endpoint.
- 401The API key is missing, invalid or revoked.
- 404The object does not exist or belongs to another integrator.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl "https://sandbox.api.ndeipi.example/v1/webhook_endpoints/we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V" \
-H "Api-Key: $NDEIPI_API_KEY"{
"id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V",
"object": "webhook_endpoint",
"url": "https://api.yourapp.example/ndeipi/webhooks",
"status": "enabled",
"event_types": [
"transfer.state_changed",
"user.kyc_status_changed"
],
"description": "Production receiver",
"public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAEu+SJIWlScv5fJmnV1iNNpGw345qGqFu0DJR6GdDIaA=\n-----END PUBLIC KEY-----\n",
"version": 2,
"created_at": "2026-10-16T09:30:00Z"
}Update a webhook endpoint
PATCH/v1/webhook_endpoints/{webhook_endpoint_id}
Returns WebhookEndpoint.
Path parameters
webhook_endpoint_idstringrequiredStarts with
we_.
Body
urlstringevent_typesarray of stringstatusstringOne of
enabled,disabled.descriptionstring
Responses
- 200The updated endpoint.
- 400The request is malformed.
- 401The API key is missing, invalid or revoked.
- 404The object does not exist or belongs to another integrator.
- 422The request is well formed but fails validation or a business rule.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl -X PATCH "https://sandbox.api.ndeipi.example/v1/webhook_endpoints/we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V" \
-H "Api-Key: $NDEIPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "enabled"
}'{
"id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V",
"object": "webhook_endpoint",
"url": "https://api.yourapp.example/ndeipi/webhooks",
"status": "enabled",
"event_types": [
"transfer.state_changed",
"user.kyc_status_changed"
],
"description": "Production receiver",
"public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAEu+SJIWlScv5fJmnV1iNNpGw345qGqFu0DJR6GdDIaA=\n-----END PUBLIC KEY-----\n",
"version": 2,
"created_at": "2026-10-16T09:30:00Z"
}Delete a webhook endpoint
DELETE/v1/webhook_endpoints/{webhook_endpoint_id}
Returns WebhookEndpoint.
Path parameters
webhook_endpoint_idstringrequiredStarts with
we_.
Responses
- 200The deleted endpoint.
- 401The API key is missing, invalid or revoked.
- 404The object does not exist or belongs to another integrator.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl -X DELETE "https://sandbox.api.ndeipi.example/v1/webhook_endpoints/we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V" \
-H "Api-Key: $NDEIPI_API_KEY"{
"id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V",
"object": "webhook_endpoint",
"url": "https://api.yourapp.example/ndeipi/webhooks",
"status": "enabled",
"event_types": [
"transfer.state_changed",
"user.kyc_status_changed"
],
"description": "Production receiver",
"public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAEu+SJIWlScv5fJmnV1iNNpGw345qGqFu0DJR6GdDIaA=\n-----END PUBLIC KEY-----\n",
"version": 2,
"created_at": "2026-10-16T09:30:00Z"
}Send a test eventComing soon
POST/v1/webhook_endpoints/{webhook_endpoint_id}/test
501 not_implemented until this operation ships.Delivers a signed webhook_endpoint.test event synchronously. A 2xx reply from the endpoint enables it.
Path parameters
webhook_endpoint_idstringrequiredStarts with
we_.
Headers
Idempotency-KeyheaderrequiredA unique key for this write, up to 255 characters. Send the same key to retry safely; see idempotency.
Responses
- 200The delivery attempt and the endpoint after it.
- 401The API key is missing, invalid or revoked.
- 404The object does not exist or belongs to another integrator.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl -X POST "https://sandbox.api.ndeipi.example/v1/webhook_endpoints/we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V/test" \
-H "Api-Key: $NDEIPI_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"{
"delivery": {
"event_id": "evt_01JA8ZH3WR2T7D0B8A5Z4Y3X2W",
"webhook_endpoint_id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V",
"attempt": 1,
"succeeded": true,
"response_status": 200,
"error": null,
"attempted_at": "2026-10-16T09:30:00Z"
},
"endpoint": {
"id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V",
"object": "webhook_endpoint",
"url": "https://api.yourapp.example/ndeipi/webhooks",
"status": "enabled",
"event_types": [
"transfer.state_changed",
"user.kyc_status_changed"
],
"description": "Production receiver",
"public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAEu+SJIWlScv5fJmnV1iNNpGw345qGqFu0DJR6GdDIaA=\n-----END PUBLIC KEY-----\n",
"version": 2,
"created_at": "2026-10-16T09:30:00Z"
}
}List events
GET/v1/events
Events are kept for 30 days and can be listed whether or not they were delivered.
Returns a page of Event objects.
Query parameters
limitintegerDefault
10.starting_afterstringCursor; an object ID. Returns the page after it. Cannot be combined with
ending_before.ending_beforestringCursor; an object ID. Returns the page before it. Cannot be combined with
starting_after.created_aftertimestampcreated_beforetimestamptypestringClients must accept types they do not recognise.
Type Object Fired when user.createdUserA user is created user.kyc_status_changedUserkyc_statuschangesuser.terms_status_changedUserterms_statuschangesuser.deactivatedUserA user is deactivated transfer.createdTransferA transfer is created, including one created by a deposit transfer.state_changedTransferAny state change deposit.receivedTransferFiat arrives for an on-ramp deposit.returnedTransferFiat is sent back to the sender payout.returnedTransferThe rail returns or rejects a payout deposit_account.deactivatedDepositAccountA deposit account is deactivated webhook_endpoint.testWebhookEndpointTest delivery object_idstringEvents whose snapshot is this object.
Responses
- 200A page of events.
- 400The request is malformed.
- 401The API key is missing, invalid or revoked.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl "https://sandbox.api.ndeipi.example/v1/events?type=transfer.state_changed&limit=20" \
-H "Api-Key: $NDEIPI_API_KEY"{
"data": [
{
"id": "evt_01JA8ZH3WR2T7D0B8A5Z4Y3X2W",
"object": "event",
"type": "transfer.state_changed",
"api_version": "v1",
"created_at": "2026-10-16T09:30:00Z",
"object_type": "transfer",
"object_version": 2,
"previous_attributes": {
"state": "pending"
},
"data": {
"id": "trf_01JA8ZC4QK7N2Y5W3V0T9S8R6P",
"object": "transfer",
"kind": "user_to_user",
"state": "completed",
"state_reason": null,
"source": {
"type": "wallet",
"wallet_id": "wal_01JA8Z4K2V9QW3H6Y7XKD2M0RS",
"user_id": "usr_01JA8Z2F5G6H7J8K9M0N1P2Q3R",
"asset": "ndeipi-points"
},
"destination": {
"type": "wallet",
"wallet_id": "wal_01JA8Z5B7C1DE2F3G4H5J6K7LM",
"user_id": "usr_01JA8Z3H6J7K8M9N0P1Q2R3S4T",
"asset": "ndeipi-points"
},
"amount": "25.00",
"deposit_instructions": null,
"receipt": {
"amount_debited": "25.00",
"amount_credited": "25.00",
"earned_amount": "0.00",
"fees": [],
"initiated_at": "2026-10-16T09:30:00Z",
"completed_at": "2026-10-16T09:30:00Z"
},
"integrator_reference": "invoice-7781",
"metadata": {
"note": "Lunch"
},
"version": 2,
"created_at": "2026-10-16T09:30:00Z",
"updated_at": "2026-10-16T09:30:00Z"
}
}
],
"has_more": false
}Get an event
GET/v1/events/{event_id}
Returns Event.
Path parameters
event_idstringrequiredStarts with
evt_.
Responses
- 200The event.
- 401The API key is missing, invalid or revoked.
- 404The object does not exist or belongs to another integrator.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl "https://sandbox.api.ndeipi.example/v1/events/evt_01JA8ZH3WR2T7D0B8A5Z4Y3X2W" \
-H "Api-Key: $NDEIPI_API_KEY"{
"id": "evt_01JA8ZH3WR2T7D0B8A5Z4Y3X2W",
"object": "event",
"type": "transfer.state_changed",
"api_version": "v1",
"created_at": "2026-10-16T09:30:00Z",
"object_type": "transfer",
"object_version": 2,
"previous_attributes": {
"state": "pending"
},
"data": {
"id": "trf_01JA8ZC4QK7N2Y5W3V0T9S8R6P",
"object": "transfer",
"kind": "user_to_user",
"state": "completed",
"state_reason": null,
"source": {
"type": "wallet",
"wallet_id": "wal_01JA8Z4K2V9QW3H6Y7XKD2M0RS",
"user_id": "usr_01JA8Z2F5G6H7J8K9M0N1P2Q3R",
"asset": "ndeipi-points"
},
"destination": {
"type": "wallet",
"wallet_id": "wal_01JA8Z5B7C1DE2F3G4H5J6K7LM",
"user_id": "usr_01JA8Z3H6J7K8M9N0P1Q2R3S4T",
"asset": "ndeipi-points"
},
"amount": "25.00",
"deposit_instructions": null,
"receipt": {
"amount_debited": "25.00",
"amount_credited": "25.00",
"earned_amount": "0.00",
"fees": [],
"initiated_at": "2026-10-16T09:30:00Z",
"completed_at": "2026-10-16T09:30:00Z"
},
"integrator_reference": "invoice-7781",
"metadata": {
"note": "Lunch"
},
"version": 2,
"created_at": "2026-10-16T09:30:00Z",
"updated_at": "2026-10-16T09:30:00Z"
}
}Redeliver an event
POST/v1/events/{event_id}/redeliver
Queues a fresh delivery of the event to one endpoint, or to every enabled endpoint subscribed to its type. The redelivery is signed with a new timestamp.
Returns Event.
Path parameters
event_idstringrequiredStarts with
evt_.
Headers
Idempotency-KeyheaderrequiredA unique key for this write, up to 255 characters. Send the same key to retry safely; see idempotency.
Body
webhook_endpoint_idstringStarts with
we_.
Responses
- 202Redelivery queued.
- 401The API key is missing, invalid or revoked.
- 404The object does not exist or belongs to another integrator.
- 429The key is over its rate limit.
- 5XXServer error. Safe to retry with the same idempotency key.
curl -X POST "https://sandbox.api.ndeipi.example/v1/events/evt_01JA8ZH3WR2T7D0B8A5Z4Y3X2W/redeliver" \
-H "Api-Key: $NDEIPI_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"webhook_endpoint_id": "we_01JA8ZG8VQ1S6C9A7Z4Y3X2W1V"
}'{
"id": "evt_01JA8ZH3WR2T7D0B8A5Z4Y3X2W",
"object": "event",
"type": "transfer.state_changed",
"api_version": "v1",
"created_at": "2026-10-16T09:30:00Z",
"object_type": "transfer",
"object_version": 2,
"previous_attributes": {
"state": "pending"
},
"data": {
"id": "trf_01JA8ZC4QK7N2Y5W3V0T9S8R6P",
"object": "transfer",
"kind": "user_to_user",
"state": "completed",
"state_reason": null,
"source": {
"type": "wallet",
"wallet_id": "wal_01JA8Z4K2V9QW3H6Y7XKD2M0RS",
"user_id": "usr_01JA8Z2F5G6H7J8K9M0N1P2Q3R",
"asset": "ndeipi-points"
},
"destination": {
"type": "wallet",
"wallet_id": "wal_01JA8Z5B7C1DE2F3G4H5J6K7LM",
"user_id": "usr_01JA8Z3H6J7K8M9N0P1Q2R3S4T",
"asset": "ndeipi-points"
},
"amount": "25.00",
"deposit_instructions": null,
"receipt": {
"amount_debited": "25.00",
"amount_credited": "25.00",
"earned_amount": "0.00",
"fees": [],
"initiated_at": "2026-10-16T09:30:00Z",
"completed_at": "2026-10-16T09:30:00Z"
},
"integrator_reference": "invoice-7781",
"metadata": {
"note": "Lunch"
},
"version": 2,
"created_at": "2026-10-16T09:30:00Z",
"updated_at": "2026-10-16T09:30:00Z"
}
}