> For the complete documentation index, see [llms.txt](https://docs.atomyx.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.atomyx.io/atomyx-submit/implementation/api-integration/callback-and-status-updates.md).

# Callback and Status Updates

Atomyx Submit can send status updates to an external system using a configured callback URL.

A callback URL is a publicly accessible endpoint in the customer system. Atomyx Submit sends an HTTP request to this URL when a submission reaches specific workflow events, such as upload, preflight completion, proof generation, approval, or rejection.

Callbacks allow the integrating system to receive updates without repeatedly polling Submit.

### How callbacks are sent

Callbacks are sent as HTTP `POST` requests with JSON payloads.

The receiving system should be prepared to accept JSON requests from Atomyx Submit.

```http
POST /your-callback-endpoint HTTP/1.1
Content-Type: application/json
```

### Authentication and signing

Atomyx Submit authenticates outbound callbacks using HMAC signatures.

The receiving system should verify the HMAC signature before trusting or processing the callback payload.

Do not place Submit API keys inside callback payloads.

Recommended implementation to confirm or adopt:

* HMAC-SHA256
* signature generated over the raw request body, or over `timestamp + "." + raw_body`
* per-tenant shared secret
* timestamp included to help prevent replay attacks

Possible header names to confirm:

```http
X-Atomyx-Signature: sha256=<hex-signature>
X-Atomyx-Timestamp: 2026-05-11T10:23:45Z
X-Atomyx-Event: preflight_passed
X-Atomyx-Delivery: del_...
User-Agent: AtomyxSubmit/<version>
```

### Callback events

Submit callbacks are triggered by submission workflow events.

Confirmed event set:

| Event              | Description                                   |
| ------------------ | --------------------------------------------- |
| `uploaded`         | File has arrived                              |
| `preflighting`     | Full preflight has started                    |
| `preflight_passed` | Preflight completed successfully              |
| `preflight_failed` | Preflight completed with failure              |
| `proof_generated`  | Proof page or proof output has been generated |
| `approved`         | Customer approved the proof                   |
| `rejected`         | Customer rejected the proof                   |

A separate `created` callback event is not currently documented. The integrating system creates the Submit session/job, so creation is normally already known by the external system.

### Callback payload

The callback body is sent as JSON.

Confirmed payload content includes:

| Field or content area        | Description                                                                                                                             |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Current submission status    | Current status such as `uploaded`, `preflighting`, `preflight_passed`, `preflight_failed`, `proof_generated`, `approved`, or `rejected` |
| File references              | URLs to generated or processed files, such as processed PDF, proof page, or preflight report                                            |
| Structured error information | Error codes, affected checks, and severity details when preflight fails                                                                 |
| `order_ref`                  | The order reference originally supplied when the session/job was created                                                                |

Recommended fields to confirm or standardise:

| Field                | Description                                    |
| -------------------- | ---------------------------------------------- |
| `event_id`           | Unique ID for the callback event               |
| `event_type`         | Event name, such as `preflight_passed`         |
| `occurred_at`        | ISO 8601 timestamp for when the event occurred |
| `session_id`         | Submit session or job ID                       |
| `order_ref`          | External order reference                       |
| `artwork_version_id` | Artwork version ID, where relevant             |
| `status`             | Current submission status                      |
| `files`              | Related file URLs                              |
| `errors`             | Structured error details                       |
| `attempt`            | Callback delivery attempt number               |

### Example payload

> The following example represents the recommended callback shape and should be confirmed against the final implementation before being treated as the official schema.

```json
{
  "event_id": "evt_123",
  "event_type": "preflight_passed",
  "occurred_at": "2026-05-11T10:23:45Z",
  "session_id": "ses_123",
  "order_ref": "ERP-12345",
  "artwork_version_id": "av_123",
  "status": "preflight_passed",
  "files": {
    "processed_pdf": "https://example.com/files/processed.pdf",
    "proof": "https://example.com/proofs/123",
    "preflight_report": "https://example.com/reports/123"
  },
  "errors": [],
  "attempt": 1
}
```

### Preflight failure payloads

When preflight fails, the callback should include structured error information.

Recommended error structure to confirm:

```json
{
  "event_id": "evt_124",
  "event_type": "preflight_failed",
  "occurred_at": "2026-05-11T10:25:00Z",
  "session_id": "ses_123",
  "order_ref": "ERP-12345",
  "status": "preflight_failed",
  "files": {
    "preflight_report": "https://example.com/reports/123"
  },
  "errors": [
    {
      "code": "LOW_RESOLUTION_IMAGE",
      "check": "image_resolution",
      "severity": "error",
      "message": "One or more images are below the required resolution."
    }
  ],
  "attempt": 1
}
```

### Expected response

Recommended behaviour to document and implement:

* any `2xx` response should be treated as successful
* `200 OK` and `204 No Content` should both be accepted
* non-2xx responses should be treated as failed delivery attempts
* timeouts should be treated as failed delivery attempts

The receiving system should respond quickly, ideally within 5 seconds.

Avoid doing long-running synchronous work inside the callback handler. A safer pattern is:

1. Verify the HMAC signature.
2. Store the callback event.
3. Return a `2xx` response.
4. Process the event asynchronously.

### Retry behaviour

Recommended behaviour to document and implement:

* retry on non-2xx responses
* retry on timeouts
* use exponential backoff
* include a unique delivery ID so the receiving system can deduplicate events
* include an attempt number
* surface permanent callback failures into Manage as workflow exceptions

Suggested retry schedule:

| Attempt | Delay      |
| ------- | ---------- |
| 1       | Immediate  |
| 2       | 1 minute   |
| 3       | 5 minutes  |
| 4       | 15 minutes |
| 5       | 1 hour     |
| 6       | 6 hours    |
| 7       | 24 hours   |

### Idempotency and duplicate events

Receiving systems should treat callbacks as at-least-once delivery.

This means the same event may be delivered more than once, especially if a response times out or a retry is triggered.

To handle this safely:

* use the event ID or delivery ID to detect duplicates
* make callback processing idempotent
* avoid assuming events always arrive exactly once
* avoid assuming callbacks always arrive in perfect order

### Security recommendations

The receiving system should:

* verify the HMAC signature before processing
* reject unsigned or invalidly signed callbacks
* use HTTPS
* check timestamps if provided
* ignore callback payloads that are too old
* avoid logging sensitive file URLs unnecessarily
* avoid exposing callback endpoints without validation


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.atomyx.io/atomyx-submit/implementation/api-integration/callback-and-status-updates.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
