Customer Metadata Pass-Through

Attach opaque, caller-owned context to RiskOS™ evaluation requests with customer_metadata and receive it unchanged in API responses and webhooks.

What customer_metadata is

customer_metadata is an optional, top-level field on the evaluation request. It holds an opaque JSON object that you define and own. RiskOS™ stores the object, forwards it to the workflow engine, and echoes it back unchanged on every outbound surface:

  • The synchronous response from POST /api/evaluation
  • Asynchronous webhook callbacks (for example, evaluation_completed, case_status_updated)

RiskOS™ doesn't transform or interpret the contents as decisioning data. Use it to carry your own context — such as the internal service, product, or business flow that started a request — so you can identify, route, and handle responses without adding custom fields per customer.

📘

Note:

For the complete evaluation request schema, including all standard fields available alongside customer_metadata, see the Evaluation API reference.


When to use customer_metadata instead of custom

Both fields accept caller-defined JSON, but they serve different purposes:

Use customer_metadata when…Use custom when…
You want context returned to you untouched, for routing or correlation.You need the data as a decisioning input for enrichments or integrations.
The data is for your systems, not for Socure to evaluate.The data feeds workflow rules, case tiles, or reporting exports.

How to include customer_metadata in a request

Add customer_metadata as a top-level sibling of id, timestamp, workflow, and data. The value must be a JSON object of your own keys and values.

curl -X POST https://riskos.sandbox.socure.com/api/evaluation \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "id": "onb-12345",
    "timestamp": "2026-06-26T08:15:30.456Z",
    "workflow": "consumer_onboarding",
    "customer_metadata": {
      "service": "checkout-api",
      "business_unit": "consumer-lending",
      "internal_ref": "order-998877"
    },
    "data": {
      "individual": {
        "given_name": "Jane",
        "family_name": "Smith",
        "email": "[email protected]"
      }
    }
  }'

You can reference the values in workflow conditions using the $request.customer_metadata.* path:

$request.customer_metadata.business_unit == "consumer-lending"

How to expect it back

In the synchronous response

When you send customer_metadata, the response echoes the same object at the top level, unchanged:

{
  "id": "onb-12345",
  "eval_id": "6dc8f39c-ecc3-4fe0-9283-fc8e5f99e816",
  "workflow": "consumer_onboarding",
  "eval_status": "evaluation_completed",
  "decision": "ACCEPT",
  "status": "CLOSED",
  "customer_metadata": {
    "service": "checkout-api",
    "business_unit": "consumer-lending",
    "internal_ref": "order-998877"
  },
  "environment_name": "Sandbox"
}

In a webhook callback

For asynchronous workflows, customer_metadata appears at the top level of the webhook envelope — a sibling of event_id, event_at, event_type, and data. It is not nested inside data.

{
  "event_id": "336ccd2a-b3a8-49a8-b2cc-89a4ae90feeb",
  "event_at": "2026-06-26T16:16:23.104744158Z",
  "event_type": "evaluation_completed",
  "customer_metadata": {
    "service": "checkout-api",
    "business_unit": "consumer-lending",
    "internal_ref": "order-998877"
  },
  "data": {
    "id": "onb-12345",
    "eval_id": "8770e076-f568-48a9-8201-dca13087e592",
    "workflow": "consumer_onboarding",
    "decision": "ACCEPT",
    "status": "CLOSED"
  }
}

To learn how to subscribe to and verify webhook events, see Webhook events.


Field constraints

ConstraintRule
TypeA JSON object ({ ... }). Arrays, strings, numbers, and booleans at the top level are rejected.
Keys and valuesAny valid JSON: string, number, boolean, array, or nested object. Designed for string-valued tags and IDs.
NestingNested objects and arrays are allowed. All nested content counts toward the size limit.
SizeUp to 200 characters total, measured across the entire serialized JSON (keys, values, braces, and quotes).
NumbersJSON numbers are preserved as numbers. For exact-fidelity identifiers, send them as strings.
🚧

Do not include sensitive data:

customer_metadata is stored and echoed verbatim. Do not place personally identifiable information (PII), secrets, or regulated data in it. Send identity data in the standard request fields under data instead.


Validation errors

ConditionHTTP statusError code
Value is not valid JSON400INVALID_REQUEST
Value is valid JSON but not an object400INVALID_REQUEST
Serialized object exceeds the character limit413CUSTOMER_METADATA_TOO_LARGE

A size violation returns a message describing the limit and the size received:

{
  "code": "CUSTOMER_METADATA_TOO_LARGE",
  "error": "customer_metadata exceeds maximum allowed size of 200 characters (received 412)"
}

Backward compatibility

customer_metadata is optional. Existing integrations are unaffected:

  • Omit the field and requests behave exactly as before.
  • Send null and RiskOS™ treats it as absent — no value is stored or echoed.
  • When the field is absent, it does not appear in the response or webhook payload.

Common use cases

  • Route webhook callbacks. Tag each request with the originating service (for example, "service": "checkout-api") and route the callback to the right internal consumer when it arrives.
  • Correlate asynchronous results. Carry your own internal_ref or order ID so you can match a paused-then-completed evaluation back to its originating transaction without server-side state management.
  • Segment by business context. Attach a business_unit, product, or environment tag so multiple teams can share one RiskOS™ integration and filter responses by their own context.
  • Standardize across products. Use one consistent context object across every internal product that calls RiskOS™, instead of requesting a custom field per customer or per team.

Related


Did this page help you?