Skip to main content

Platform guide

Send receipts from a custom script

Use the API directly from PHP, Python, cron jobs, backend scripts, and internal tools.

Scriptable API

Use this when your workflow already runs in code

A script can log what triggered the run, what was produced, whether a person needs to review it, and what happened next. Send summaries instead of full private payloads unless your workflow really needs the full content stored in the receipt.

What you need

API key and endpoint

Create an API key in Automation Receipts and send requests to https://automationreceipts.com/api/v1/runs.

JSON-capable HTTP client

Use curl, PHP cURL, file_get_contents, Python requests, or the HTTP client your runtime already provides.

Minimal curl example

Create a run

curl -X POST "https://automationreceipts.com/api/v1/runs" \
  -H "Authorization: Bearer aar_live_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
    "automation_name": "Nightly Account Summary",
    "run_uid": "cron-20260517-1042",
    "source_type": "custom_script",
    "trigger_type": "scheduled_cron",
    "status": "completed",
    "risk_level": "low",
    "input_summary": "Cron job checked accounts updated in the last 24 hours.",
    "output_summary": "A short account activity summary was generated.",
    "approval_required": false,
    "approval_status": "not_required",
    "final_action": "Summary saved for the operations team."
  }'

On success, create-run returns HTTP 201 with run_id, run_uid, and receipt_url. Use receipt_url as the human-readable receipt page.

PHP examples

PHP with curl

<?php

$apiKey = 'aar_live_REPLACE_ME';
$url = 'https://automationreceipts.com/api/v1/runs';

$payload = [
    'automation_name' => 'Nightly Account Summary',
    'run_uid' => 'cron-' . date('Ymd-His'),
    'source_type' => 'custom_script',
    'trigger_type' => 'scheduled_cron',
    'status' => 'completed',
    'risk_level' => 'low',
    'input_summary' => 'Cron job checked accounts updated in the last 24 hours.',
    'output_summary' => 'A short account activity summary was generated.',
    'model_used' => 'gpt-5.5',
    'approval_required' => false,
    'approval_status' => 'not_required',
    'final_action' => 'Summary saved for the operations team.',
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

echo $statusCode . PHP_EOL;
echo $response . PHP_EOL;

PHP with file_get_contents

<?php

$apiKey = 'aar_live_REPLACE_ME';
$payload = json_encode([
    'automation_name' => 'Team AI Tool',
    'run_uid' => 'tool-' . bin2hex(random_bytes(8)),
    'source_type' => 'custom_script',
    'status' => 'needs_review',
    'risk_level' => 'medium',
    'input_summary' => 'A teammate asked the tool to draft a vendor follow-up.',
    'output_summary' => 'A vendor follow-up message was drafted.',
    'approval_required' => true,
    'approval_status' => 'pending',
    'final_action' => 'Draft held for review.',
]);

$context = stream_context_create([
    'http' => [
        'method' => 'POST',
        'header' => "Authorization: Bearer {$apiKey}\r\nContent-Type: application/json\r\n",
        'content' => $payload,
        'ignore_errors' => true,
    ],
]);

echo file_get_contents('https://automationreceipts.com/api/v1/runs', false, $context);

PowerShell example

Create a run from PowerShell

$headers = @{
  Authorization = "Bearer aar_live_REPLACE_ME"
  "Content-Type" = "application/json"
}

$body = @{
  automation_name = "PowerShell Report Drafter"
  run_uid = "ps-$(Get-Date -Format yyyyMMdd-HHmmss)"
  source_type = "custom_script"
  trigger_type = "manual_script"
  status = "completed"
  risk_level = "low"
  input_summary = "Script gathered open tickets from the team report."
  output_summary = "Tickets were summarized for the support lead."
  approval_required = $false
  approval_status = "not_required"
  final_action = "Summary posted to the team dashboard."
} | ConvertTo-Json

Invoke-RestMethod -Method Post -Uri "https://automationreceipts.com/api/v1/runs" -Headers $headers -Body $body

Append an event later

If your script continues after the initial receipt, append timeline events using the original run_uid, not the numeric run_id.

Append event request

curl -X POST "https://automationreceipts.com/api/v1/runs/cron-20260517-1042/events" \
  -H "Authorization: Bearer aar_live_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "action_taken",
    "event_label": "Summary saved",
    "event_summary": "The script saved the generated summary for the operations team."
  }'

Cron and internal tool guidance

Create stable unique IDs

Use a timestamp, UUID, job execution ID, or database ID for run_uid. Retrying the exact same ID can create a duplicate response instead of a new receipt.

Log summaries, not dumps

Receipts should explain the run. Avoid raw emails, documents, secrets, API keys, and large model payloads unless you have a clear reason to store them.

Check the response

Treat HTTP 201 as success. Log or alert on 401, 409, 413, and 422 responses so failures are visible.

Retry carefully

If you retry after a network failure, decide whether the retry should reuse the same run_uid or create a new receipt for a new attempt.

Common responses

Status Meaning What to check
201Run created.Open the returned receipt_url.
400Valid JSON object required.Check JSON encoding and headers.
401Missing or invalid bearer token.Use the full active API key in the Authorization header.
409Duplicate run_uid.Generate a new unique ID for a new run.
413Payload too large.Keep request bodies at or below 131072 bytes.
422Validation error.Check required fields and allowed values.

Next steps