Delivers an external event to a workflow instance that is waiting on a wait_event step.
Delivers an external event to a workflow instance that is waiting on a wait_event step.
When the event matches a step the instance is waiting for, the instance resumes execution from that step. This endpoint is idempotent: submitting the same event again after it was already processed returns status: "already_processed" instead of resuming the workflow twice.
Use HTTP Basic auth with your PayMongo secret key as the username and an empty password. Include
Organization-Id: <your organization id>on every request.
Request
POST https://workflow-api.paymongo.com/v1/instances/{id}/eventsPath parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The workflow instance ID that is waiting for the event. |
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | HTTP Basic auth credentials generated from your secret key and an empty password. |
Organization-Id | string | Yes | Your organization ID. Must match the organization that owns the secret key. |
Content-Type | string | Yes | Must be application/json. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
event_name | string | Yes | Name of the event the instance is waiting for. Must match the wait_event step's configured event name. |
payload | object | No | Arbitrary JSON data to pass into the workflow with the event. Maximum serialized size is 64 KB. If the waiting step declares a payload_schema, the payload is validated against it. |
{
"event_name": "approval_received",
"payload": {
"approved_by": "user_123",
"decision": "approved"
}
}Response
Returns the result of the submission wrapped in a top-level data object. HTTP 200 OK is returned for both accepted submissions and idempotent replays.
| Field | Type | Description |
|---|---|---|
data.instance_id | string | The workflow instance the event was submitted to. |
data.step_index | integer | Zero-based index of the wait_event step that received the event. |
data.event_name | string | The event name that was submitted. |
data.status | string | Submission status. One of accepted or already_processed. |
data.processed_at | string | RFC 3339 timestamp for when the submission was processed. |
Status values
| Value | Meaning |
|---|---|
accepted | The event was matched to a waiting step and the workflow was signaled to resume. |
already_processed | This event had already been delivered and processed; no action was taken. |
Example request
curl -X POST https://workflow-api.paymongo.com/v1/instances/winst_ghi789/events \
-u sk_test_xxxxxxxxxxxxxxxx: \
-H "Organization-Id: org_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"event_name": "approval_received",
"payload": { "approved_by": "user_123", "decision": "approved" }
}'Example response
{
"data": {
"instance_id": "winst_ghi789",
"step_index": 2,
"event_name": "approval_received",
"status": "accepted",
"processed_at": "2026-06-18T04:30:00Z"
}
}Optional: Idempotent replay response
Submitting the same event again after it was already processed returns 200 OK with status: "already_processed".
{
"data": {
"instance_id": "winst_ghi789",
"step_index": 2,
"event_name": "approval_received",
"status": "already_processed",
"processed_at": "2026-06-18T04:31:10Z"
}
}Errors
Errors return a top-level errors array. Each error includes a machine-readable code and a human-readable detail.
| HTTP status | Code | When it happens |
|---|---|---|
400 Bad Request | invalid_request_body | Body is not valid JSON, event_name is missing, or the id path segment is empty. |
400 Bad Request | missing_organization_id | Organization-Id is missing on a non-superuser request. |
400 Bad Request | invalid_event_payload | The payload cannot be serialized, or exceeds the 64 KB limit. |
400 Bad Request | invalid_payload_schema | The payload failed validation against the waiting step's payload_schema. |
400 Bad Request | invalid_instance_status | The instance exists but is not in a running state, so it cannot accept events. |
403 Forbidden | livemode_mismatch | The instance belongs to a different mode than the secret key. |
404 Not Found | instance_not_found | No instance with that ID exists for this organization. Also returned when the instance belongs to another organization. |
404 Not Found | wait_state_not_found | The instance is not waiting for an event with that event_name. |
409 Conflict | event_window_expired | The waiting step already timed out or failed; the event can no longer be delivered. |
409 Conflict | wait_state_cancelled | The waiting step was cancelled and can no longer receive events. |
422 Unprocessable Entity | step_not_waiting | The matched step is in an unexpected non-waiting state. |
500 Internal Server Error | internal_server_error | Failed to signal the workflow, or another unexpected server error occurred. |
Example error
{
"errors": [
{
"code": "wait_state_not_found",
"detail": "wait state not found"
}
]
}Mode behavior
Mode is derived from the secret key prefix. An sk_test_… key operates in test mode (livemode = false), and an sk_live_… key operates in live mode (livemode = true). A resource created in one mode is only visible to keys of the same mode.