Log inTalk to us
Reference and AI

Metadata

Metadata lets your application keep its own business attributes on Ivora objects: which site host owns a charger, a revenue share percentage, a contract ID. Ivora stores the pairs and returns them on every read, webhook and agent tool result; your systems keep the logic. Semantics follow Stripe's metadata.

flowchart diagram; its source follows
Diagram source
flowchart LR
  App[Your application] -->|create or PATCH metadata| Station[Station or location]
  Station -->|copied when it starts| Snapshot["Session, bill or transaction: station_metadata, location_metadata"]
  App -->|filter by key and value| Lists[List filters]
  Snapshot --> Lists
  Station -.->|never| OCPI[OCPI roaming partners]

Objects that carry metadata

ObjectWrite it withScope
StationPOST /v1/tenants/{tenant_id}/stations, PATCH …/stations/{station_id}stations:write
LocationPOST /v1/tenants/{tenant_id}/locations, PATCH …/locations/{location_id}stations:write
ProjectPOST /v1/teams/{team_id}/projects, PATCH /v1/tenants/{tenant_id}the team's owners and admins (projects:manage)
TariffPOST /v1/tenants/{tenant_id}/tariffs, PATCH …/tariffs/{tariff_id}tariffs:write
RFID tokenPOST /v1/tenants/{tenant_id}/tokens, PATCH …/tokens/{token_id}tokens:write
BillPOST /v1/tenants/{tenant_id}/bills, PATCH …/bills/{bill_id}billing:write
Charging session (application-managed)POST /v1/tenants/{tenant_id}/charging-sessions, PATCH …/charging-sessions/{session_id}billing:write

A charging session is its bill: the session and its bill show the same metadata, and changing one changes the other. Metadata extends external_reference, which stays: use external_reference for the one identifier you look an object up by, and metadata for everything else.

Transactions are the charger's own records and have no metadata of their own; they carry the snapshot below.

Set, merge and delete

metadata is an object of string keys and string values.

  • Create sets the pairs given.
  • PATCH merges: keys you send are set, keys you leave out keep their values, and a key sent as "" or null is deleted. Sending only metadata changes nothing else on the object.
curl -X PATCH https://api.ivoracharge.com/v1/tenants/18/stations/1042 \
  -H "Authorization: Bearer $IVORA_API_KEY" -H "Idempotency-Key: host-move-1042-01" \
  -H "Content-Type: application/json" \
  -d '{"metadata": {"host_id": "h-17", "revenue_share_pct": "30", "old_contract": null}}'

Every write is idempotent with its Idempotency-Key like the object's other writes. Station edits answer 202 with an operation whose result is the station; the other objects answer with the object itself.

Limits

RuleLimitError
Keys per object (after a merge)50422 metadata_too_many_keys (details.limit, details.keys)
Key1–40 characters of A–Z a–z 0–9 _ . -422 metadata_key_invalid
Valuea string of at most 500 characters422 metadata_value_invalid

Values are strings only: numbers, booleans and nested objects are refused, so send "30", not 30. A refused request changes nothing. See Errors and statuses.

Not for secrets or personal data. Metadata is returned to everyone who can read the object, delivered in webhooks and written to the project's audit log. Never store card data, credentials, driver names, emails or phone numbers.

Snapshots: attribution that survives edits

When a bill or a charging session is created, and when the charger starts a transaction, Ivora copies the station's and its location's metadata into station_metadata and location_metadata. The snapshot never changes afterwards, so a monthly report by site host stays correct after a charger changes hosts. The session's or bill's own metadata stays writable.

Objectstation_metadata, location_metadata taken
Bill, charging sessionWhen it is created
TransactionWhen the charging core records it (within seconds of the start). Transactions that started before snapshots existed have {}

An object whose station or location had no metadata has {}. Deleting a station or location deletes its own metadata but never a snapshot.

Filter lists

These lists accept metadata[key]=value query parameters: an exact match, combined with AND across keys and with the list's other filters (at most 10 metadata filters). The filters run on indexed values, so per-host queries stay fast, and pages stay full.

Listmetadata[key] matchesSnapshot filters
GET …/stationsthe station's metadata—
GET …/locationsthe location's metadata—
GET …/billsthe bill's metadatastation_metadata[key], location_metadata[key]
GET …/charging-sessionsthe session's metadatastation_metadata[key], location_metadata[key]
GET …/transactionsthe station's metadata nowstation_metadata[key], location_metadata[key] (at the start)
# A site host's sessions in October, attributed as they were when each one started.
curl -G https://api.ivoracharge.com/v1/tenants/18/transactions \
  -H "Authorization: Bearer $IVORA_API_KEY" \
  --data-urlencode "station_metadata[host_id]=h-17" \
  --data-urlencode "started_from=2026-10-01T00:00:00Z" \
  --data-urlencode "started_to=2026-11-01T00:00:00Z"

A malformed filter (a key outside the rules, an empty value, the same key with two values) answers 400 invalid_request. In the OpenAPI document the filters are deepObject query parameters named metadata, station_metadata and location_metadata; agent tools take them as objects.

Where metadata appears

  • Reads and lists of every object above.
  • Webhooks: events that carry an object carry its metadata: token.* (token), tariff.updated and tariff.archived (tariff; a metadata change is in changes.metadata), bill.finalized (the bill with its snapshot), charging_session.status_changed (session) and operation.completed of a station edit (result).
  • AI agents: the MCP tools return it, list tools take the filters as objects, and update_bill_metadata and update_external_session_metadata change a bill's or session's metadata (Agent integration).
  • Audit log: every change records a metadata.updated entry in the project's audit log with the object, the keys set (values cut to 100 characters) and the keys deleted (Audit log).

Never published to roaming partners

OCPI partners never receive metadata: locations, EVSEs, tariffs, tokens, sessions and charge detail records are published without it, whatever its keys. Other projects never see it either: metadata belongs to its project and is read and written with the project's own access only.