Skip to content

Surfaces

Interactive API Explorer: Explorer

The authoritative surface is the OpenAPI spec:

  • /crm/openapi.yaml

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

Surface Types (explicit)

API Gateway

  • Status: Available.
  • Base: https://api.g3nretailstack.com/crm
  • Notes: Primary tenant surface for CRM and loyalty workflows.

Direct Lambda

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

CLI

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

MCP

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

Auth + tenancy

  • Required headers: x-orgcode and x-session-guid (user session) or x-api-key (org-bound service account).
  • 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).
  • Facility context: x-logical-guid (required for operational actions; see OpenAPI per-path). x-channel-code (required where documented; see OpenAPI per-path).

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/crm/<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.
  • Header auth is canonical; body session_guid / api_key is accepted where documented.

Customer surfaces

  • POST /crm/customer/create|get|list|search
  • POST /crm/customer/dedupe/list
  • POST /crm/customer/merge|merge/list
  • POST /crm/customer/consent/set|get
  • POST /crm/customer/fraud/assess|fraud/list
  • POST /crm/customer/hold/list|hold/resolve
  • POST /crm/customer/flag/set|flag/list

B2B account surfaces

  • POST /crm/account/create|get|list|status/set|update
  • POST /crm/account/contact/create|get|list|status/set|update

Tax exemption certificate surfaces

  • POST /crm/exemption/certificate/create|get|list
  • POST /crm/exemption/certificate/status/set

Comments and inbox surfaces

  • POST /crm/comment|comment/get|comment/list|comment/revise|comment/status|comment/report
  • POST /crm/inbox/create|get|list|status|state

Endpoint inventory (OpenAPI parity)

Request/response schema names reference OpenAPI component schemas.

MethodPathRequest schemaResponse schema
POST/account/contact/createAccountContactCreateRequestAccountContactEnvelope
POST/account/contact/getAccountContactGetRequestAccountContactEnvelope
POST/account/contact/listAccountContactListRequestAccountContactListEnvelope
POST/account/contact/status/setAccountContactStatusSetRequestAccountContactEnvelope
POST/account/contact/updateAccountContactUpdateRequestAccountContactEnvelope
POST/account/createAccountCreateRequestAccountEnvelope
POST/account/getAccountGetRequestAccountEnvelope
POST/account/listAccountListRequestAccountListEnvelope
POST/account/status/setAccountStatusSetRequestAccountEnvelope
POST/account/updateAccountUpdateRequestAccountEnvelope
POST/commentCommentAddRequestCommentEnvelope
POST/comment/getCommentGetRequestCommentEnvelope
POST/comment/listCommentListRequestCommentListEnvelope
POST/comment/reportCommentReportRequestCommentReportEnvelope
POST/comment/reviseCommentReviseRequestCommentEnvelope
POST/comment/statusCommentStatusRequestCommentEnvelope
POST/customer/consent/getCustomerConsentGetRequestCustomerConsentEnvelope
POST/customer/consent/setCustomerConsentSetRequestCustomerConsentEnvelope
POST/customer/createCustomerCreateRequestCustomerEnvelope
POST/customer/dedupe/listCustomerDedupeRequestCustomerDedupeEnvelope
POST/customer/flag/listCustomerFlagListRequestCustomerFlagListEnvelope
POST/customer/flag/setCustomerFlagSetRequestCustomerFlagEnvelope
POST/customer/fraud/assessCustomerFraudAssessRequestCustomerFraudAssessEnvelope
POST/customer/fraud/listCustomerFraudListRequestCustomerFraudListEnvelope
POST/customer/getCustomerGetRequestCustomerEnvelope
POST/customer/hold/listCustomerHoldListRequestCustomerHoldListEnvelope
POST/customer/hold/resolveCustomerHoldResolveRequestCustomerHoldEnvelope
POST/customer/listCustomerListRequestCustomerListEnvelope
POST/customer/mergeCustomerMergeRequestCustomerEnvelope
POST/customer/merge/listCustomerMergeListRequestCustomerMergeListEnvelope
POST/customer/searchCustomerSearchRequestCustomerListEnvelope
POST/exemption/certificate/createExemptionCertificateCreateRequestExemptionCertificateEnvelope
POST/exemption/certificate/getExemptionCertificateGetRequestExemptionCertificateEnvelope
POST/exemption/certificate/listExemptionCertificateListRequestExemptionCertificateListEnvelope
POST/exemption/certificate/status/setExemptionCertificateStatusSetRequestExemptionCertificateEnvelope
POST/giftcard/issueStoredValueIssueRequestStoredValueEnvelope
POST/giftcard/redeemStoredValueRedeemRequestStoredValueEnvelope
POST/inbox/createInboxCreateRequestInboxEnvelope
POST/inbox/getInboxGetRequestInboxEnvelope
POST/inbox/listInboxListRequestInboxListEnvelope
POST/inbox/stateInboxStateRequestInboxEnvelope
POST/inbox/statusInboxStatusRequestInboxEnvelope
POST/loyalty/adjustLoyaltyAdjustRequestLoyaltyTxnEnvelope
POST/loyalty/earnLoyaltyEarnRequestLoyaltyTxnEnvelope
POST/loyalty/expireLoyaltyExpireRequestLoyaltyExpireEnvelope
POST/loyalty/policy/getLoyaltyPolicyGetRequestLoyaltyPolicyEnvelope
POST/loyalty/policy/setLoyaltyPolicySetRequestLoyaltyPolicyEnvelope
POST/loyalty/redeemLoyaltyRedeemRequestLoyaltyTxnEnvelope
POST/loyalty/restoreLoyaltyRestoreRequestLoyaltyTxnEnvelope
POST/loyalty/reverseLoyaltyReverseRequestLoyaltyTxnEnvelope

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": "crm", "timestamp_utc": "2026-01-21T00:00:00Z" }
}

Error envelope (shape-only):

json
{
  "success": false,
  "error": {
    "error_code": "crm.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": "3", "current_revision": "4" },
    "conflict_snapshot": { "revision": 4 }
  },
  "build": { "...": "..." },
  "stats": { "call": "example", "service": "crm", "timestamp_utc": "2026-01-21T00:00:00Z", "request_id": "req-123" }
}

Role requirements (by endpoint family)

  • Read/list/search: crm_view (or owner).
  • Customer updates: crm_manage / crm_edit (or owner).
  • Privacy/consent: crm_privacy_admin (or owner).
  • Loyalty: loyalty_admin (or owner).
  • Stored value: giftcard_admin (or owner).

Idempotency & retries

  • Use expected_revision for updates to revisioned customer records.
  • Loyalty earn/redeem are not idempotent unless documented.

Common pitfalls

  • Consent flags gate exports and some reads.
  • Anti-enumeration returns 404 for non-associated callers.

Examples (core families)

Customer create

json
{ "customer": { "email": "cust@example.com", "caption": "Jane Doe" }, "reason": "signup" }

Response (shape):

json
{ "success": true, "data": { "customer_id": "CUSTOMER_ID" }, "build": { "...": "..." }, "stats": { "...": "..." } }

Loyalty earn

json
{ "customer_id": "CUSTOMER_ID", "points": 100, "reason": "purchase" }

Response (shape):

json
{ "success": true, "data": { "loyalty_txn_id": "LOYALTY_ID" }, "build": { "...": "..." }, "stats": { "...": "..." } }