Queue failed event invite-list records for retry
Only the initiating actor may retry an event_invitees operation for this event in failed/completed_with_errors state. Verifies durable failed donor IDs, then queues a new operation for failed rows only using the original accepted context. A stable retry key recovers the same new operation. Successful/skipped rows are not retried. Requires event setup management; archived event invitation history is read-only (409).
curl --request POST \
--url https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry \
--header 'Authorization: Bearer <token>' \
--header 'Idempotency-Key: <idempotency-key>'import requests
url = "https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry"
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Idempotency-Key': '<idempotency-key>', Authorization: 'Bearer <token>'}
};
fetch('https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry', 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.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Idempotency-Key: <idempotency-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://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
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.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"message": "Invite-list work queued.",
"status": "processing",
"operation_id": "550e8400-e29b-41d4-a716-446655440000",
"bulk_operation": {
"operation_id": "550e8400-e29b-41d4-a716-446655440000",
"type": "event_invitees",
"status": "processing",
"total_items": 42,
"processed_items": 42,
"failed_items": 42,
"skipped_items": 42,
"updated_items": 42,
"progress_percent": 42,
"message": "Example",
"created_at": "2026-10-20T12:00:00Z",
"updated_at": "2026-10-20T12:00:00Z",
"completed_at": "2026-10-20T12:00:00Z",
"stalled": false,
"failed_record_ids": [
42
],
"has_failed_records": false,
"skipped_reasons": {},
"context": {
"schema_version": 42,
"event_id": 42,
"owner_user_id": 42,
"selection_mode": "selected_rows",
"selection_fingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"plan": {
"id": 42,
"name": "Personal invitation",
"revision": 1,
"definition_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"steps": [
{
"step_key": "personal_call",
"label": "Personal call",
"task_title_template": "Call {donor_name} about {event_name}",
"invitation_method": "phone_call",
"days_before_event": 28,
"due_date": "2026-11-01",
"assignee_strategy": "invitee_owner",
"resolved_assignee_user_id": 42,
"assignee_user_id": 42,
"enabled": false
}
],
"enabled_step_count": 42,
"new_task_count": 42
},
"communications_sent": false,
"retry_of_operation_id": "550e8400-e29b-41d4-a716-446655440000"
}
},
"communications_sent": false
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"message": "Version, idempotency, preview or archived-event conflict.",
"error_code": "event_invitee_conflict",
"details": {
"current_version": 42,
"current_lock_version": 42,
"current_revision": 42,
"current_definition_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}Authorizations
Passport bearer token authentication for legacy admin sessions.
Headers
Nonblank retry key of at most 255 characters, bound to the actor and operation. Reuse unchanged for the same accepted request.
255"invitation-request-1"
Path Parameters
Record ID in the authenticated organization.
42
Source bulk invitation operation UUID.
"550e8400-e29b-41d4-a716-446655440000"
Response
Queue failed event invite-list records for retry completed.
Queue message.
"Invite-list work queued."
Current operation status.
processing, completed, completed_with_errors, failed "processing"
Operation UUID.
"550e8400-e29b-41d4-a716-446655440000"
Show child attributes
Show child attributes
Always false.
false
curl --request POST \
--url https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry \
--header 'Authorization: Bearer <token>' \
--header 'Idempotency-Key: <idempotency-key>'import requests
url = "https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry"
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Idempotency-Key': '<idempotency-key>', Authorization: 'Bearer <token>'}
};
fetch('https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry', 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.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Idempotency-Key: <idempotency-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://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
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.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/events/{eventId}/invitees/selection/operations/{operationId}/retry")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"message": "Invite-list work queued.",
"status": "processing",
"operation_id": "550e8400-e29b-41d4-a716-446655440000",
"bulk_operation": {
"operation_id": "550e8400-e29b-41d4-a716-446655440000",
"type": "event_invitees",
"status": "processing",
"total_items": 42,
"processed_items": 42,
"failed_items": 42,
"skipped_items": 42,
"updated_items": 42,
"progress_percent": 42,
"message": "Example",
"created_at": "2026-10-20T12:00:00Z",
"updated_at": "2026-10-20T12:00:00Z",
"completed_at": "2026-10-20T12:00:00Z",
"stalled": false,
"failed_record_ids": [
42
],
"has_failed_records": false,
"skipped_reasons": {},
"context": {
"schema_version": 42,
"event_id": 42,
"owner_user_id": 42,
"selection_mode": "selected_rows",
"selection_fingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"plan": {
"id": 42,
"name": "Personal invitation",
"revision": 1,
"definition_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"steps": [
{
"step_key": "personal_call",
"label": "Personal call",
"task_title_template": "Call {donor_name} about {event_name}",
"invitation_method": "phone_call",
"days_before_event": 28,
"due_date": "2026-11-01",
"assignee_strategy": "invitee_owner",
"resolved_assignee_user_id": 42,
"assignee_user_id": 42,
"enabled": false
}
],
"enabled_step_count": 42,
"new_task_count": 42
},
"communications_sent": false,
"retry_of_operation_id": "550e8400-e29b-41d4-a716-446655440000"
}
},
"communications_sent": false
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"message": "Version, idempotency, preview or archived-event conflict.",
"error_code": "event_invitee_conflict",
"details": {
"current_version": 42,
"current_lock_version": 42,
"current_revision": 42,
"current_definition_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}