curl --request POST \
--url https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver \
--header 'X-Integrator-Key: <api-key>' \
--header 'X-Signature: <api-key>' \
--header 'X-Timestamp: <api-key>'import requests
url = "https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver"
headers = {
"X-Signature": "<api-key>",
"X-Integrator-Key": "<api-key>",
"X-Timestamp": "<api-key>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Signature': '<api-key>',
'X-Integrator-Key': '<api-key>',
'X-Timestamp': '<api-key>'
}
};
fetch('https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver', 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://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-Integrator-Key: <api-key>",
"X-Signature: <api-key>",
"X-Timestamp: <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"
"net/http"
"io"
)
func main() {
url := "https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-Signature", "<api-key>")
req.Header.Add("X-Integrator-Key", "<api-key>")
req.Header.Add("X-Timestamp", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver")
.header("X-Signature", "<api-key>")
.header("X-Integrator-Key", "<api-key>")
.header("X-Timestamp", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Signature"] = '<api-key>'
request["X-Integrator-Key"] = '<api-key>'
request["X-Timestamp"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "6a7441a013a0c37c0d1facfe",
"eventId": "<string>",
"status": "pending",
"attempts": 1,
"nextAttemptAt": "2023-11-07T05:31:56Z",
"event": "onramp.completed",
"webhookUrl": "https://api.example.com/webhooks",
"payload": {
"schemaVersion": "1",
"eventId": "<string>",
"sequence": 2,
"occurredAt": "2023-11-07T05:31:56Z",
"userId": "<string>",
"id": "dep_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"deposit": {
"id": "dep_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"asset": "USDC",
"destinationAddressDisplay": "9xQeWv…wM9R",
"principalAmountUsd": "<string>",
"totalDebitAmountUsd": "<string>",
"confirmedReleasedAmountUsd": "<string>",
"debitStatus": "authorized",
"releaseStatus": "not_started",
"releaseDecisionMode": "after_settlement",
"instantPortionUsd": "<string>",
"settlementPortionUsd": "<string>",
"userFeeUsd": "<string>"
},
"fundingSource": {
"id": "fs_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"institutionName": "<string>",
"accountMask": "<string>"
},
"event": "achDebit.authorized",
"milestone": "authorized",
"achReturn": {
"id": "dr_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"amountUsd": "<string>",
"cryptoStateAtReturn": "not_released",
"userAction": "review_required"
}
},
"success": true,
"responseStatus": 200,
"error": "getaddrinfo ENOTFOUND webhooks.example.com",
"timestamp": "2023-11-07T05:31:56Z"
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}{
"title": "Unauthorized",
"status": 401,
"type": "urn:problem-type:auth:unauthorized",
"detail": "Bearer token required",
"instance": "<string>",
"realm": "API",
"scope": "read:users"
}{
"title": "<string>",
"status": 404,
"resourceType": "user",
"resourceId": "<string>",
"type": "about:blank",
"detail": "<string>",
"instance": "<string>"
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}Redeliver a webhook delivery
Sends a webhook delivery again and returns the delivery with status: "pending".
The redelivery uses the same payload, the same eventId, and the same delivery id (sent as the Spritz-Delivery-Id header), so a handler that deduplicates on eventId processes it at most once. Signatures are recomputed at send time with your current webhook secret. It goes to the webhook’s current URL and starts a fresh retry schedule (about 24 hours); attempts keeps counting from its previous value.
Use it after fixing your endpoint for a delivery that ended failed. You can also redeliver a succeeded or pending delivery; a pending one is attempted again promptly instead of at its scheduled time. Follow progress with GET /v1/integrator/webhooks/deliveries.
Not found (404): code: "WEBHOOK_DELIVERY_NOT_FOUND" means no delivery with this ID exists for your integrator.
Conflict (409): code: "WEBHOOK_NOT_FOUND" (retryable: false) means the webhook this delivery was sent to has been deleted. Create a webhook and reconcile the event from the API instead.
curl --request POST \
--url https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver \
--header 'X-Integrator-Key: <api-key>' \
--header 'X-Signature: <api-key>' \
--header 'X-Timestamp: <api-key>'import requests
url = "https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver"
headers = {
"X-Signature": "<api-key>",
"X-Integrator-Key": "<api-key>",
"X-Timestamp": "<api-key>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Signature': '<api-key>',
'X-Integrator-Key': '<api-key>',
'X-Timestamp': '<api-key>'
}
};
fetch('https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver', 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://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-Integrator-Key: <api-key>",
"X-Signature: <api-key>",
"X-Timestamp: <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"
"net/http"
"io"
)
func main() {
url := "https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-Signature", "<api-key>")
req.Header.Add("X-Integrator-Key", "<api-key>")
req.Header.Add("X-Timestamp", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver")
.header("X-Signature", "<api-key>")
.header("X-Integrator-Key", "<api-key>")
.header("X-Timestamp", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.spritz.finance/v1/integrator/webhooks/deliveries/{deliveryId}/redeliver")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Signature"] = '<api-key>'
request["X-Integrator-Key"] = '<api-key>'
request["X-Timestamp"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "6a7441a013a0c37c0d1facfe",
"eventId": "<string>",
"status": "pending",
"attempts": 1,
"nextAttemptAt": "2023-11-07T05:31:56Z",
"event": "onramp.completed",
"webhookUrl": "https://api.example.com/webhooks",
"payload": {
"schemaVersion": "1",
"eventId": "<string>",
"sequence": 2,
"occurredAt": "2023-11-07T05:31:56Z",
"userId": "<string>",
"id": "dep_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"deposit": {
"id": "dep_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"asset": "USDC",
"destinationAddressDisplay": "9xQeWv…wM9R",
"principalAmountUsd": "<string>",
"totalDebitAmountUsd": "<string>",
"confirmedReleasedAmountUsd": "<string>",
"debitStatus": "authorized",
"releaseStatus": "not_started",
"releaseDecisionMode": "after_settlement",
"instantPortionUsd": "<string>",
"settlementPortionUsd": "<string>",
"userFeeUsd": "<string>"
},
"fundingSource": {
"id": "fs_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"institutionName": "<string>",
"accountMask": "<string>"
},
"event": "achDebit.authorized",
"milestone": "authorized",
"achReturn": {
"id": "dr_01K3NQ4QGM7Y5ZP0DRW1M4V8NC",
"amountUsd": "<string>",
"cryptoStateAtReturn": "not_released",
"userAction": "review_required"
}
},
"success": true,
"responseStatus": 200,
"error": "getaddrinfo ENOTFOUND webhooks.example.com",
"timestamp": "2023-11-07T05:31:56Z"
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}{
"title": "Unauthorized",
"status": 401,
"type": "urn:problem-type:auth:unauthorized",
"detail": "Bearer token required",
"instance": "<string>",
"realm": "API",
"scope": "read:users"
}{
"title": "<string>",
"status": 404,
"resourceType": "user",
"resourceId": "<string>",
"type": "about:blank",
"detail": "<string>",
"instance": "<string>"
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}Authorizations
HMAC signature authentication for backend integrators.
Required Headers:
- X-Integrator-Key: Integrator API key (format: ik_...)
- X-Signature: HMAC signature (format: sha256={hex})
- X-Timestamp: Unix timestamp in milliseconds
- Authorization: Bearer {user-api-key}
Signature Algorithm: HMAC-SHA256
Signature Format: {timestamp}.{METHOD}.{path}.{bodyHash}
- timestamp: Unix timestamp in milliseconds
- METHOD: HTTP method in UPPERCASE (GET, POST, etc.)
- path: Request path (e.g., /v1/transactions)
- bodyHash: SHA256 hex digest of request body (empty string if no body)
Timestamp Tolerance: ±5 minutes (300 seconds)
Example: For POST /v1/transactions with body {"amount":100} and timestamp 1234567890000: Payload: 1234567890000.POST./v1/transactions.{sha256(body)} Signature: sha256=abc123...
Integrator API key (format: ik_...) used with HMAC authentication
Unix timestamp in milliseconds for request freshness. Must be within 5 minutes of server time. The timestamp alone bounds but does not prevent an exact replay within that window. Use Idempotency-Key on supported mutations.
Path Parameters
The delivery id from GET /v1/integrator/webhooks/deliveries or the Spritz-Delivery-Id header
^[a-fA-F\d]{24}$Response
Response for status 200
Stable delivery ID, sent as the Spritz-Delivery-Id header on every attempt and redelivery. Pass it to POST /v1/integrator/webhooks/deliveries/{deliveryId}/redeliver.
"6a7441a013a0c37c0d1facfe"
The eventId of the delivered event, the same on every attempt and redelivery. Deduplicate on it. null for events sent without one.
pending: Spritz will retry at nextAttemptAt. succeeded: your endpoint returned a 2xx (terminal). failed: retries are exhausted or your endpoint returned a non-retryable status (terminal); redeliver it once your endpoint is fixed.
pending, succeeded, failed Total HTTP attempts made for this delivery so far, across retries and redeliveries. null when not recorded.
x >= 0When Spritz will next attempt this delivery. Set only while status is pending; otherwise null. Not a guarantee of exact timing.
The event that was delivered
"onramp.completed"
The URL the delivery was attempted against
"https://api.example.com/webhooks"
The exact body that was sent, and the body the signature was computed over. ACH debit, off-ramp, and credit on-ramp milestone events use the versioned semantic payload variants; other event families use their resource-change payload.
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
- Option 6
- Option 7
- Option 8
- Option 9
- Option 10
- Option 11
- Option 12
- Option 13
- Option 14
- Option 15
- Option 16
- Option 17
Show child attributes
Show child attributes
Whether Spritz received a successful response. false alongside an error does not mean your endpoint rejected the event — it may have processed it and only the response was lost. false with neither error nor responseStatus means the outcome was never recorded, not that it failed. Read those two fields before concluding anything about delivery.
true
HTTP status your endpoint returned — but only when error is absent. When error is set no response was received at all, and this is Spritz's classification of the failure (504 for a timeout, 500 otherwise) rather than anything your endpoint said.
200
Set when no usable response was received — a timeout, a refused connection, a DNS or certificate problem. This does not prove the request never arrived: a refused connection means it did not, but a timeout or a dropped connection may mean your endpoint received and fully processed it and we never heard back. Treat delivery as unknown and rely on idempotent handling. When error is absent the request landed and responseStatus is your endpoint's own answer.
"getaddrinfo ENOTFOUND webhooks.example.com"
When the delivery was attempted. Absent on a handful of very early records that predate the field — omitted rather than guessed.