Working with Metadata
Use the flexible metadata field to store custom information.
What is Metadata?
The metadata field is a flexible key-value object available on customers, vendors, and sessions. Use it to store any custom data relevant to your application.
Note: Donation intents do not support metadata. If you need to associate custom data with donations, use metadata on customers, vendors, or sessions instead.
Common Use Cases
{
"name": "Jane Doe",
"metadata": {
"email": "[email protected]",
"source": "web",
"customer_since": "2025-01-01",
"external_id": "cust_123456",
"subscription_tier": "premium"
}
}Store email addresses, external system IDs, acquisition source, and other customer attributes.
{
"name": "Downtown Coffee Shop",
"metadata": {
"location": "123 Main St, Seattle, WA",
"type": "retail",
"manager": "John Doe",
"store_id": "STORE-001",
"phone": "+1-555-0100"
}
}Track physical locations, managers, store IDs, contact information, and business type.
{
"type": "add_on",
"amount": 500,
"metadata": {
"order_id": "ORD-12345",
"transaction_id": "txn_abc123",
"source": "checkout",
"user_agent": "Mozilla/5.0..."
}
}Link sessions to orders, transactions, and track where the donation originated.
Supported Data Types
Metadata values can be strings, numbers, booleans, or null. Nested objects and arrays are supported.
{
"metadata": {
"string_value": "text",
"number_value": 123,
"boolean_value": true,
"null_value": null,
"nested_object": {
"key": "value"
},
"array_value": ["item1", "item2"]
}
}Best Practices
- Use consistent key names across your application
- Store email addresses in metadata since there's no dedicated email field
- Include external system IDs to link records between systems
- Document your metadata schema for team reference
- Avoid storing sensitive information like passwords or credit card numbers
- Keep metadata reasonably sized - avoid storing large binary data
Updating Metadata
When updating a resource, metadata fields are merged with the existing metadata. New keys are added, existing keys are updated with new values, and keys not included in the update remain unchanged. This is a shallow merge - nested objects are replaced entirely, not merged recursively.
Original metadata:
{
"metadata": {
"email": "[email protected]",
"source": "web",
"customer_since": "2025-01-01"
}
}Update request (partial):
{
"metadata": {
"email": "[email protected]",
"verified": true
}
}Result after merge:
{
"metadata": {
"email": "[email protected]",
"source": "web",
"customer_since": "2025-01-01",
"verified": true
}
}Notice how source and customer_since were preserved even though they weren't included in the update. The email was updated, and verified was added.
Original metadata:
{
"metadata": {
"email": "[email protected]",
"preferences": {
"newsletter": true,
"notifications": true,
"theme": "dark"
}
}
}Update request:
{
"metadata": {
"preferences": {
"newsletter": false
}
}
}Result after merge:
{
"metadata": {
"email": "[email protected]",
"preferences": {
"newsletter": false
}
}
}Important: The preferences object was completely replaced. The original notifications and theme fields were lost because the merge is shallow. If you need to preserve nested fields, read the current metadata first, modify it, and send the complete nested object back.
Querying by Metadata
The current API version does not support filtering or searching by metadata fields. To find records by metadata values, retrieve all records and filter client-side, or maintain a separate index in your application.