Monitor and Recover Gaming Inventory Uploads

Gaming Inventory processing is asynchronous. Customer integrations are responsible for discovering the trace created by every upload, polling it to a terminal status, and recovering safely when processing fails.

Non-negotiable monitoring rules

For every brand:

  1. Permit only one upload at a time.
  2. Record the UTC upload time, source version, file checksum, and game count.
  3. Discover the processing trace through GET /logs/recent.
  4. Store the trace ID in your own durable run record.
  5. Poll GET /logs/trace/{traceId} with backoff.
  6. Treat COMPLETED as terminal technical completion, then reconcile the exported game-code set.
  7. Alert and stop later uploads when the result is FAILED, remains non-terminal beyond your agreed processing window, or fails reconciliation.

Do not infer success from:

  • HTTP 200 from /validate;
  • a successful upload-form response;
  • a successful file-transfer status;
  • the presence of a trace; or
  • completed individual steps while the main log is still non-terminal.

Find recent traces

curl --silent --show-error --fail-with-body \
  --request GET \
  --url 'https://api.opti-x.optimove.net/inventory/v1/logs/recent' \
  --header 'x-api-key: {{service_api_key}}' \
  --header 'x-brand-key: {{brand_key}}'

The implementation queries traces for the authorised brand from up to the previous 24 hours, most recent first. It stops after approximately 1,000 raw main-and-step items, so busy brands can receive only a subset:

{
  "traces": [
    {
      "traceId": "example-version-id",
      "mainLog": {
        "traceId": "example-version-id",
        "recordType": "MAIN",
        "brandKey": "123",
        "fileName": "brand/123/inventory/games.json",
        "fileSize": 4281,
        "status": "STARTED",
        "timestamp": "2026-01-01T12:00:05+00:00"
      },
      "steps": []
    }
  ],
  "count": 1,
  "total_items": 1,
  "filtered_incomplete": 0
}

The trace may not appear immediately after the file upload. Retry with bounded exponential backoff—for example, after 2, 5, 10, 20 and then 30 seconds—without starting another upload.

Identify a trace using the recorded upload time and the fact that no other upload for that brand is allowed to overlap. Persist its traceId; recent logs are a discovery aid, not a durable audit store.

Read one trace

curl --silent --show-error --fail-with-body \
  --request GET \
  --url 'https://api.opti-x.optimove.net/inventory/v1/logs/trace/{{trace_id}}' \
  --header 'x-api-key: {{service_api_key}}' \
  --header 'x-brand-key: {{brand_key}}'

The response has two parts:

  • mainLog is the authoritative overall result.
  • steps show the stages that started, completed or failed and can help diagnose an error.

Important main-log fields:

FieldMeaning
traceIdUnique identifier for this processing run. Treat it as an opaque string, capture it, and retain it for support diagnostics
timestampUTC time at which processing was logged
brandKeyBrand whose catalogue was processed
fileNameUploaded file name
fileSizeUploaded size in bytes
statusOverall processing status
processedRows0 when no common-inventory change was detected; otherwise the full post-difference inventory row count returned by the processor. It is not a create/update delta.
durationProcessing duration in milliseconds
errorMessageOverall failure detail when status is FAILED

Status handling

Main statusTerminal?Integration behaviour
STARTEDNoContinue polling; keep the per-brand upload lock
COMPLETEDYesRecord technical completion, then reconcile the exported Inventory view before marking the run successful or releasing the upload lock
FAILEDYesMark the run failed, alert and keep automated later uploads blocked until recovery is approved

Step records can use STARTED, COMPLETED and FAILED. A failed step normally identifies where processing stopped, but the terminal processing decision must use mainLog.status. Business success additionally requires reconciliation.

Reconcile the exported inventory view

A COMPLETED trace means the processor returned without an exception. It does not guarantee that a large removal was applied consistently: current safety controls can suppress part of a deletion of more than half the catalogue while the trace still completes.

After every completed run:

  1. Confirm stepMetadata.inventory_rows on the completed GET_DATA step equals the submitted root-object game count. This proves the processor read the expected file.
  2. After the normal downstream propagation period agreed during onboarding, call GET /download.
  3. Decompress the CSV and compare its game_code count and set with the intended snapshot.
  4. When that exported view matches, mark the customer-side reconciliation complete and release the per-brand upload lock.
  5. Continue monitoring event-to-inventory joins and representative recommendation results; no public endpoint currently confirms that your full inventory is being served.
  6. If the export does not match within the agreed window, alert, block later uploads and provide both code sets and the trace ID to Optimove support.
curl --silent --show-error --fail-with-body \
  --request GET \
  --url 'https://api.opti-x.optimove.net/inventory/v1/download' \
  --header 'x-api-key: {{service_api_key}}' \
  --header 'x-brand-key: {{brand_key}}' \
  --output processed-inventory.csv.gz

The export is a processed, replicated view and can lag the trace. It is useful for game-code reconciliation, but it is not a lossless copy of every submitted field, has no public immediate-consistency guarantee, and cannot prove cross-store atomicity. Keep your submitted snapshot as the source of truth. Never send a snapshot removing more than half the catalogue through the normal flow; coordinate that operation with Optimove.

Trace logs have finite platform retention and are not your audit store. Keep your own run record and exact submitted file for the period required by your organisation.

Recommended run record

Store at least:

{
  "brand_key": "123",
  "source_version": "catalogue-2026-01-01T12:00:00Z",
  "upload_started_at": "2026-01-01T12:00:00Z",
  "file_sha256": "example-sha256",
  "submitted_game_count": 120,
  "trace_id": "example-version-id",
  "status": "COMPLETED",
  "processed_rows": 120,
  "export_reconciliation_status": "MATCHED",
  "exported_game_count": 120,
  "processing_duration_ms": 6842,
  "monitoring_completed_at": "2026-01-01T12:00:12Z"
}

When present, compare stepMetadata.inventory_rows on the completed GET_DATA step with your submitted game count. Interpret processedRows using the table above; do not treat it as a change count.

Request a submitted version for a trace

Use the trace download endpoint when you need to attempt retrieval of the file version associated with a run:

curl --silent --show-error \
  --request GET \
  --url 'https://api.opti-x.optimove.net/inventory/v1/logs/trace/{{trace_id}}/download' \
  --header 'x-api-key: {{service_api_key}}' \
  --header 'x-brand-key: {{brand_key}}' \
  --dump-header trace-download-headers.txt \
  --output trace-download-response.json

For an authorised trace record, the API returns HTTP 302 with a temporary URL in the Location header. That URL is valid for one hour. Fetch it in a second request without forwarding the Gaming Inventory API credentials to that URL.

Treat download as best-effort: the temporary URL can still fail on retrieval, and a stored version is not guaranteed to be available for every trace. Download diagnostics promptly and always retain your own submitted file; this endpoint is not a durable archive.

The endpoint can return:

StatusMeaning
302Temporary download URL created; this does not prove the storage object/version still exists
403The trace belongs to another brand
404Trace record not found
500The download URL could not be created

The temporary storage URL can separately return a missing-key or missing-version error.

Recovery after FAILED

Do not retry blindly. Use this sequence:

  1. Keep later uploads for the brand blocked.
  2. Save the full trace response, including errorMessage and all steps.
  3. Attempt to download the trace version; if it is unavailable, use the exact submitted file retained in your run archive.
  4. Compare its checksum, game count and game-code set with the run record.
  5. Correct the problem in your authoritative catalogue or export process.
  6. Generate a new complete snapshot from the current authoritative state.
  7. Repeat local checks and call /validate with the entire corrected file.
  8. Request a new upload form and submit the corrected snapshot once.
  9. Capture the new trace ID and monitor it independently to COMPLETED.
  10. Reconcile its exported game-code count and set.
  11. Link the recovery trace to the failed trace in your run history.

Never upload a small patch file to repair one bad game. A later file is another complete snapshot, so a patch would make every omitted game a deletion candidate.

Recovery when no trace appears

If the temporary upload request succeeded but no new trace appears:

  1. Confirm the multipart file upload itself returned a successful status.
  2. Confirm all signed fields from /upload were submitted unchanged.
  3. Confirm the form had not expired.
  4. Poll /logs/recent with bounded backoff for the recorded brand and upload time.
  5. Do not upload again while the first upload's state is unknown.
  6. If no trace appears within your agreed processing window, contact Optimove support with the brand key, UTC upload time, file checksum, upload response status and captured response headers.

Alerting recommendations

Create alerts for:

  • a FAILED main status;
  • no trace discovered within the agreed window;
  • a trace remaining STARTED beyond the agreed window;
  • a GET_DATA inventory-row count that differs from the submitted game count;
  • a catalogue count drop or unexpected set of removed game codes;
  • repeated validation failures; and
  • an attempted overlapping upload.

See Troubleshooting for common causes and fixes.


Did this page help you?