Skip to content

Surfaces

Interactive API Explorer: Explorer

The authoritative surface is the OpenAPI spec:

  • /ipm/openapi.yaml

Additional surfaces are available: MCP (/ipm/mcp.html) and CLI (g3n ipm ...; see cli/README.md).

Surface Types (explicit)

API Gateway

  • Status: Available.
  • Base: https://api.g3nretailstack.com/ipm
  • Notes: Primary tenant surface for integrations (webhooks, CDC, bulk jobs, KPI).

Direct Lambda

  • Status: Not offered.
  • Notes: No direct Lambda surface is documented for IPM.

CLI

  • Status: Available.
  • Command: g3n ipm ... (API Gateway).
  • Notes: See cli/README.md.

MCP

  • Status: Available.
  • Canonical protocol: https://mcp.g3nretailstack.com/ipm/PROTOCOL.md
  • Mirror: https://doc.g3nretailstack.com/ipm/PROTOCOL.md

Auth + tenancy

  • Auth headers: x-session-guid (user session) or x-api-key (org-bound service account) are required for all API Gateway calls, including /stat.
  • Tenant endpoints require x-orgcode (health checks do not).
  • Header auth is canonical; body auth is accepted where documented. See /common/headers-identity.html.
  • Optional cost attribution: x-cccode (or request field cccode) where supported; see OpenAPI.
  • Non-associated callers receive 404 not-found (anti-enumeration).

Identifier policy

  • Direct get/update/status calls require GUID/ID fields (*_id or legacy *_guid where that is the canonical field name). Code-based lookups are resolve/search only.
  • Responses never include both *_id and *_guid for the same record (no dual-field output).
  • Exceptions (email-based UAS, PVM resolve, MRS container+record_id) are listed in /common/ids-codes.html.

Request builder (API Gateway)

Headers (canonical)

bash
-H "x-orgcode: $ORGCODE"
-H "x-session-guid: $SESSION_GUID" # or: -H "x-api-key: $API_KEY"
-H "content-type: application/json"

Template

bash
curl -sS -X POST "https://api.g3nretailstack.com/ipm/<endpoint>" \
  -H "content-type: application/json" \
  -H "x-orgcode: $ORGCODE" \
  -H "x-session-guid: $SESSION_GUID" \
  -d '{"...": "..."}'

Notes

  • Replace <endpoint> with a route from the OpenAPI inventory.
  • Health checks may omit x-orgcode; tenant routes require it.
  • Header auth is canonical; body session_guid / api_key is accepted where documented.

Endpoint inventory (OpenAPI parity)

Request/response schema names reference OpenAPI component schemas.

MethodPathRequest schemaResponse schema
POST/bulk/export/continueBulkExportContinueRequestEnvelope + data.job (BulkJob)
POST/bulk/export/createBulkExportCreateRequestEnvelope + data.job (BulkJob)
POST/bulk/import/commitBulkImportCommitRequestEnvelope + data.job (BulkJob)
POST/bulk/import/continueBulkImportContinueRequestEnvelope + data.job (BulkJob)
POST/bulk/import/createBulkImportCreateRequestEnvelope + data.job (BulkJob) + upload_url
POST/bulk/job/getBulkJobGetRequestEnvelope + data.job (BulkJob) + download_url/report_url
POST/bulk/job/listBulkJobListRequestEnvelope + data.items (BulkJob[])
POST/cdc/listCdcListRequestEnvelope + data.items + next_token
POST/event/catalog/listEventCatalogListRequestEnvelope + data.items + next_token
POST/export/contract/listExportContractListRequestEnvelope + data.contracts (ExportContract[]) + next_token
POST/kpi/alertKpiAlertRequestEnvelope + data.alert (KpiAlert)
POST/kpi/queryKpiQueryRequestEnvelope + data.series (KpiSnapshot[]) + next_token
POST/kpi/recordKpiRecordRequestEnvelope + data.kpi (KpiSnapshot)
POST/lifecycle/listLifecycleListRequestEnvelope + data.items + version
POST/pagination/getPaginationGetRequestEnvelope
POST/specimen/getSpecimenGetRequestEnvelope + data (specimen)
POST/webhook/createWebhookCreateRequestEnvelope + data.webhook (Webhook) + signing_secret
POST/webhook/getWebhookGetRequestEnvelope + data.webhook (Webhook)
POST/webhook/listWebhookListRequestEnvelope + data.items (Webhook[])
POST/webhook/replayWebhookReplayRequestEnvelope + data (webhook_id, delivered, failed)
POST/webhook/status/setWebhookStatusSetRequestEnvelope + data.webhook (Webhook)

Webhook delivery payload

Webhook POST body:

json
{
  "delivered_at": "2026-02-01T00:00:00Z",
  "webhook_id": "whk-123",
  "delivery_reason": "live",
  "event": { "event_id": "evt-123", "reason": "status-set", "service": "pvm", "action": "variant-updated" }
}
  • delivery_reason: live (normal delivery), retry (automatic retry), or replay (manual replay).
  • The event payload includes its own reason (why the event occurred); delivery_reason explains why this delivery attempt was sent.

Webhook secrets & rotation

  • signing_secret is returned once on webhook create; get/list only return secret_last4.
  • Secrets are stored encrypted at rest (DynamoDB SSE) and never emitted in logs/events.
  • Rotation posture (current): create a new webhook, verify delivery, then revoke the old webhook to avoid downtime.
  • If a dedicated rotate endpoint is introduced, it will return the new secret once and enforce an overlap window (UNCONFIRMED).
  • Treat webhook secrets as credentials; store in a secrets manager and rotate immediately on exposure.

Error tags

Common tags (see /common/error-tags.html for definitions): validation-error, unauthorized, forbidden, not-found, expected-revision-required, conflict, invalid-state, throttled, internal-error.

Example envelopes

Success envelope (shape-only):

json
{
  "success": true,
  "data": { "example": "see schema for fields" },
  "build": { "build_major": "MONDAY", "build_minor": "0000000000", "build_id": "MONDAY-0000000000" },
  "stats": { "call": "example", "service": "ipm", "timestamp_utc": "2026-01-24T00:00:00Z" }
}

Error envelope (shape-only):

json
{
  "success": false,
  "error": {
    "error_code": "ipm.conflict_revision",
    "http_status": 409,
    "retryable": false,
    "request_id": "req-123",
    "trace_id": "trace-abc",
    "major": { "tag": "conflict", "message": { "en_US": "Expected revision does not match the current record." } },
    "details": { "expected_revision": "rev-3", "current_revision": "rev-4" },
    "conflict_snapshot": { "revision": "rev-4" }
  },
  "build": { "...": "..." },
  "stats": { "call": "example", "service": "ipm", "timestamp_utc": "2026-01-24T00:00:00Z", "request_id": "req-123" }
}

Export contract (event stream alignment)

  • POST /ipm/export/contract/list
  • Optional filters: service, limit, next_token.
  • Returns per-service contract metadata (stream, format, partitioning, schema URL, actions).

Example request:

json
{
  "service": "scm",
  "limit": 25
}

KPI snapshots

  • POST /ipm/kpi/record — record a KPI snapshot (write).
  • POST /ipm/kpi/query — query KPI snapshots by bucket and time window (read).
  • POST /ipm/kpi/alert — record a KPI alert and optionally deliver to inbox.

Example record:

json
{
  "request_context": { "orgcode": "ORG1", "actor": "user:U1", "context_source": "session" },
  "reason": "kpi-rollup",
  "source_refs": [{ "kind": "job", "id": "job_123" }],
  "kpi": {
    "kpi_code": "inventory_stockout_rate",
    "scope": "facility",
    "logical_guid": "LOG1",
    "bucket": "daily",
    "bucket_start": "2026-01-25T00:00:00Z",
    "bucket_end": "2026-01-26T00:00:00Z",
    "value": 0.034,
    "value_unit": "ratio",
    "dimensions": { "channel_code": "pos" }
  }
}

Role requirements (by endpoint family)

  • Read/list: integration_view (or owner).
  • Webhook/CDC/bulk management: integration_admin (or owner).

Idempotency & retries

  • Job creation is not idempotent unless documented; use caller-provided IDs where supported.
  • Status updates require expected_revision when present.

Common pitfalls

  • CDC cursors are opaque; persist and replay from stored cursors.
  • Webhook verification tokens expire; verify promptly.

Examples (core families)

Webhook register

json
{ "webhook": { "target_url": "https://example.com/webhook", "filters": [{ "service": "scm", "action_prefix": "order-" }] }, "reason": "integration" }

Response (shape):

json
{ "success": true, "data": { "webhook_id": "WH_ID" }, "build": { "...": "..." }, "stats": { "...": "..." } }

CDC list (cursor)

json
{ "cursor": "CURSOR", "limit": 100, "reason": "sync" }

Response (shape):

json
{ "success": true, "data": { "items": [], "next_cursor": "NEXT" }, "build": { "...": "..." }, "stats": { "...": "..." } }

Example query:

json
{
  "kpi_code": "inventory_stockout_rate",
  "scope": "facility",
  "logical_guid": "LOG1",
  "bucket": "daily",
  "from_utc": "2026-01-01T00:00:00Z",
  "to_utc": "2026-01-31T00:00:00Z",
  "limit": 30
}

Example alert:

json
{
  "request_context": { "orgcode": "ORG1", "actor": "user:U1", "context_source": "session" },
  "reason": "threshold-breach",
  "source_refs": [{ "kind": "kpi_snapshot", "id": "kpi_123" }],
  "alert": {
    "kpi_code": "inventory_stockout_rate",
    "value": 0.12,
    "threshold": { "comparator": "gt", "value": 0.1 },
    "scope": "facility",
    "logical_guid": "LOG1",
    "bucket": "daily",
    "bucket_start": "2026-01-25T00:00:00Z",
    "bucket_end": "2026-01-26T00:00:00Z",
    "team_guid": "TEAM1",
    "inbox_service": "scm",
    "priority": "high"
  }
}