Skip to content
Back to Steward

Metadata

metadata is a free-form key-value store on an application. Use it to carry your own identifiers (your internal customer id, the plan a customer is on, which of your systems created the record) so you can correlate Steward data with your own without maintaining a separate mapping table.

Steward never interprets metadata. It is stored and returned verbatim, and nothing in scoring, screening, or workflow behaviour reads it.

It is also not included in exports. An exported application carries the record itself, not your annotations on it. If you need your own identifiers to travel with an export, carry them from the application read instead of expecting them in the file.

Warning: Because it is returned on every read of the application, do not put anything sensitive in metadata: no personal data beyond an opaque identifier, no secrets, no card or account numbers.

Send metadata when creating an application, or PATCH it later:

Terminal window
curl -X PATCH https://api.getsteward.ai/api/v1/applications/{id} \
-H "Authorization: Bearer stw_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "metadata": { "externalRef": "abc-123", "plan": "enterprise" } }'

This is the part that most often surprises people. A PATCH merges into the existing metadata rather than replacing it. Keys you do not mention are left alone.

Starting from { "externalRef": "abc-123", "plan": "enterprise" }:

You send Result Why
{"plan": "starter"} {"externalRef": "abc-123", "plan": "starter"} plan updated, externalRef untouched
{"region": "eu"} all three keys New key added to the existing set
{"plan": null} {"externalRef": "abc-123"} A null value deletes that one key
{} no metadata at all An empty object clears everything
metadata omitted entirely unchanged Absent means “don’t touch metadata”
{"metadata": null} 400 Rejected: send {} if you mean to clear

Two of these are easy to get wrong:

  • To remove a single key, set it to null: not "". An empty string is a valid value and stores an empty string.
  • {} clears everything. If you build a patch object programmatically and it happens to come out empty, you will wipe the metadata rather than no-op. Omit the field entirely when you have nothing to change.

Because there is no replace mode, “set metadata to exactly this” is two steps if you need it: send {} to clear, then send the new set.

Rule Limit
Number of keys 50 (counted after the merge is applied)
Key length 1–40 characters
Key characters Letters, digits, hyphens, and underscores only
Value type String (numbers, booleans, objects, and arrays are rejected)
Value length Up to 500 characters

The key limit is enforced against the merged result, so a patch that is small on its own can still fail if it would push the total past 50. Both the shape rules and the key-count check return 400 with a message naming the offending key.

Values must be strings. Serialise anything structured yourself:

{ "metadata": { "orderCount": "42", "flags": "{\"beta\":true}" } }

metadata comes back on the application from both GET /applications and GET /applications/{id}. An application with no metadata returns null rather than {}, so guard before indexing into it.

Metadata changes are recorded in the audit trail, which reports which keys were added, modified, or removed. The values themselves are not written into the audit entry.