Ingest events in batch
curl --request POST \
--url https://api.scrip.dev/v1/events/batch \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"events": [
{
"event_data": {},
"event_timestamp": "2024-01-15T10:30:00Z",
"idempotency_key": "order-12345-completed",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_abc123",
"participant_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient_external_id": "user_xyz789",
"recipient_id": "550e8400-e29b-41d4-a716-446655440001"
}
]
}
'import requests
url = "https://api.scrip.dev/v1/events/batch"
payload = { "events": [
{
"event_data": {},
"event_timestamp": "2024-01-15T10:30:00Z",
"idempotency_key": "order-12345-completed",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_abc123",
"participant_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient_external_id": "user_xyz789",
"recipient_id": "550e8400-e29b-41d4-a716-446655440001"
}
] }
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
events: [
{
event_data: {},
event_timestamp: '2024-01-15T10:30:00Z',
idempotency_key: 'order-12345-completed',
program_id: '550e8400-e29b-41d4-a716-446655440000',
external_id: 'user_abc123',
participant_id: '550e8400-e29b-41d4-a716-446655440000',
recipient_external_id: 'user_xyz789',
recipient_id: '550e8400-e29b-41d4-a716-446655440001'
}
]
})
};
fetch('https://api.scrip.dev/v1/events/batch', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.scrip.dev/v1/events/batch",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'events' => [
[
'event_data' => [
],
'event_timestamp' => '2024-01-15T10:30:00Z',
'idempotency_key' => 'order-12345-completed',
'program_id' => '550e8400-e29b-41d4-a716-446655440000',
'external_id' => 'user_abc123',
'participant_id' => '550e8400-e29b-41d4-a716-446655440000',
'recipient_external_id' => 'user_xyz789',
'recipient_id' => '550e8400-e29b-41d4-a716-446655440001'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.scrip.dev/v1/events/batch"
payload := strings.NewReader("{\n \"events\": [\n {\n \"event_data\": {},\n \"event_timestamp\": \"2024-01-15T10:30:00Z\",\n \"idempotency_key\": \"order-12345-completed\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"external_id\": \"user_abc123\",\n \"participant_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"recipient_external_id\": \"user_xyz789\",\n \"recipient_id\": \"550e8400-e29b-41d4-a716-446655440001\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.scrip.dev/v1/events/batch")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"events\": [\n {\n \"event_data\": {},\n \"event_timestamp\": \"2024-01-15T10:30:00Z\",\n \"idempotency_key\": \"order-12345-completed\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"external_id\": \"user_abc123\",\n \"participant_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"recipient_external_id\": \"user_xyz789\",\n \"recipient_id\": \"550e8400-e29b-41d4-a716-446655440001\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/events/batch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"events\": [\n {\n \"event_data\": {},\n \"event_timestamp\": \"2024-01-15T10:30:00Z\",\n \"idempotency_key\": \"order-12345-completed\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"external_id\": \"user_abc123\",\n \"participant_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"recipient_external_id\": \"user_xyz789\",\n \"recipient_id\": \"550e8400-e29b-41d4-a716-446655440001\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"error_count": 1,
"results": [
{
"error": "program_id: This field is required",
"error_code": "validation_error",
"event": {
"event_timestamp": "2024-01-15T10:30:00Z",
"external_id": "user_abc123",
"id": "550e8400-e29b-41d4-a716-446655440000",
"idempotency_key": "order-12345-completed",
"participant_id": "550e8400-e29b-41d4-a716-446655440002",
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "PENDING"
},
"index": 0,
"status": "accepted"
}
],
"success_count": 9,
"total": 10
}{
"code": "bad_request",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Missing or invalid credentials"
}{
"code": "forbidden",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Insufficient permissions for this action"
}{
"code": "unsupported_media_type",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Content-Type must be application/json"
}{
"code": "internal_error",
"message": "An internal error occurred"
}Events
Ingest events in batch
Submit up to 100 events in a single request. Events are accepted or rejected independently, with a per-event outcome in results.
POST
/
v1
/
events
/
batch
Ingest events in batch
curl --request POST \
--url https://api.scrip.dev/v1/events/batch \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"events": [
{
"event_data": {},
"event_timestamp": "2024-01-15T10:30:00Z",
"idempotency_key": "order-12345-completed",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_abc123",
"participant_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient_external_id": "user_xyz789",
"recipient_id": "550e8400-e29b-41d4-a716-446655440001"
}
]
}
'import requests
url = "https://api.scrip.dev/v1/events/batch"
payload = { "events": [
{
"event_data": {},
"event_timestamp": "2024-01-15T10:30:00Z",
"idempotency_key": "order-12345-completed",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_abc123",
"participant_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient_external_id": "user_xyz789",
"recipient_id": "550e8400-e29b-41d4-a716-446655440001"
}
] }
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
events: [
{
event_data: {},
event_timestamp: '2024-01-15T10:30:00Z',
idempotency_key: 'order-12345-completed',
program_id: '550e8400-e29b-41d4-a716-446655440000',
external_id: 'user_abc123',
participant_id: '550e8400-e29b-41d4-a716-446655440000',
recipient_external_id: 'user_xyz789',
recipient_id: '550e8400-e29b-41d4-a716-446655440001'
}
]
})
};
fetch('https://api.scrip.dev/v1/events/batch', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.scrip.dev/v1/events/batch",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'events' => [
[
'event_data' => [
],
'event_timestamp' => '2024-01-15T10:30:00Z',
'idempotency_key' => 'order-12345-completed',
'program_id' => '550e8400-e29b-41d4-a716-446655440000',
'external_id' => 'user_abc123',
'participant_id' => '550e8400-e29b-41d4-a716-446655440000',
'recipient_external_id' => 'user_xyz789',
'recipient_id' => '550e8400-e29b-41d4-a716-446655440001'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.scrip.dev/v1/events/batch"
payload := strings.NewReader("{\n \"events\": [\n {\n \"event_data\": {},\n \"event_timestamp\": \"2024-01-15T10:30:00Z\",\n \"idempotency_key\": \"order-12345-completed\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"external_id\": \"user_abc123\",\n \"participant_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"recipient_external_id\": \"user_xyz789\",\n \"recipient_id\": \"550e8400-e29b-41d4-a716-446655440001\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.scrip.dev/v1/events/batch")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"events\": [\n {\n \"event_data\": {},\n \"event_timestamp\": \"2024-01-15T10:30:00Z\",\n \"idempotency_key\": \"order-12345-completed\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"external_id\": \"user_abc123\",\n \"participant_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"recipient_external_id\": \"user_xyz789\",\n \"recipient_id\": \"550e8400-e29b-41d4-a716-446655440001\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/events/batch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"events\": [\n {\n \"event_data\": {},\n \"event_timestamp\": \"2024-01-15T10:30:00Z\",\n \"idempotency_key\": \"order-12345-completed\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"external_id\": \"user_abc123\",\n \"participant_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"recipient_external_id\": \"user_xyz789\",\n \"recipient_id\": \"550e8400-e29b-41d4-a716-446655440001\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"error_count": 1,
"results": [
{
"error": "program_id: This field is required",
"error_code": "validation_error",
"event": {
"event_timestamp": "2024-01-15T10:30:00Z",
"external_id": "user_abc123",
"id": "550e8400-e29b-41d4-a716-446655440000",
"idempotency_key": "order-12345-completed",
"participant_id": "550e8400-e29b-41d4-a716-446655440002",
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "PENDING"
},
"index": 0,
"status": "accepted"
}
],
"success_count": 9,
"total": 10
}{
"code": "bad_request",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Missing or invalid credentials"
}{
"code": "forbidden",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Insufficient permissions for this action"
}{
"code": "unsupported_media_type",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Content-Type must be application/json"
}{
"code": "internal_error",
"message": "An internal error occurred"
}Submits up to 100 events in a single request. Each event in the batch is accepted and processed independently. Individual events can succeed or fail without affecting the others.
The response returns
Batch ingestion follows the same semantics as single-event ingestion. Each event requires an
202 Accepted with total, success_count, error_count, and a results array in the same order as the input. Each result has a status of accepted or error. Failed entries carry a machine-readable error_code (e.g. validation_error, bad_request, program_not_found) and a human-readable error message; accepted entries include the full event object. Shape and validation errors are reported per event in this response; valid events are still accepted and processed even when siblings fail. Business validation and processing happen asynchronously after acceptance.
A 400 is returned only when the batch envelope itself is malformed (unparseable JSON, zero events, or more than 100 events).
{
"total": 2,
"success_count": 1,
"error_count": 1,
"results": [
{ "index": 0, "status": "accepted", "event": { "id": "..." } },
{ "index": 1, "status": "error", "error_code": "validation_error", "error": "program_id: This field is required" }
]
}
idempotency_key scoped to its program_id. Duplicate keys return the same event identity without reprocessing. To correct or replace an event, use a new idempotency key.
Check individual event statuses via the get event endpoint or by polling the list endpoint with the relevant filters. As with single-event ingestion, accepted IDs may briefly 404 in queue-based ingestion mode until the async consumer materializes them; poll until each ID resolves.
For usage patterns and examples, see the Event Processing guide.
Authorizations
ApiKeyAuthBearerAuth
API key passed in the X-API-Key header.
Body
application/json
Batch of events
Events is a list of events to ingest (max 100 per request).
Required array length:
1 - 100 elementsShow child attributes
Show child attributes
Response
Batch accepted for async processing
ErrorCount is the number of events that failed
Example:
1
Results contains the outcome for each event
Show child attributes
Show child attributes
SuccessCount is the number of events successfully ingested
Example:
9
Total is the number of events in the request
Example:
10
⌘I