External Sources
Collections can connect to external APIs like Stripe, Salesforce, or any REST endpoint. Agents use the same manage_record and query_records tools — they don't know whether data lives in Rekor or an external system.
How It Works
Add a sources config to any collection. Each source defines API endpoints, authentication, and field mapping. When a record operation includes an external_source that matches a configured source, Rekor proxies the operation to the external API.
rekor collections upsert invoices \
--name "Invoices" \
--schema '{"type":"object","properties":{"amount":{"type":"number"},"status":{"type":"string"}}}' \
--sources '[{
"name": "stripe",
"auth": {
"header": "Authorization",
"value_template": "Bearer {{secret}}",
"secret": "sk_live_..."
},
"field_mapping": {
"to_external": {
"amount": "amount_due",
"status": "invoice_status"
}
},
"get": { "url": "https://api.stripe.com/v1/invoices/{{external_id}}", "method": "GET", "response_path": "data" },
"list": { "url": "https://api.stripe.com/v1/invoices", "method": "GET", "response_path": "data", "total_path": "total_count" },
"create": { "url": "https://api.stripe.com/v1/invoices", "method": "POST" },
"update": { "url": "https://api.stripe.com/v1/invoices/{{external_id}}", "method": "POST" }
}]'
Agent Experience
The agent uses the exact same tools for proxied and native records:
# Proxied to Stripe API
manage_record(upsert, collection: "invoices", external_id: "inv_123", external_source: "stripe", data: {amount: 5000})
# Stored in Rekor
manage_record(upsert, collection: "notes", data: {title: "Follow up"})
Field Mapping DSL
Map between Rekor's canonical schema and external API formats. Supports simple renames and rich transformations.
Simple Rename
{ "status": "invoice_status" }
Nested Path
{ "customer_name": { "path": "account.contact.full_name" } }
Enum Mapping
{ "status": { "path": "state", "values": { "active": "ACTIVE", "draft": "DRAFT" } } }
Type Transform
{ "amount": { "path": "total", "transform": "to_number" } }
Available transforms: lowercase, uppercase, trim, to_string, to_number, to_boolean, iso_date
Default Values
{ "currency": { "path": "currency", "default": "usd" } }
Array Access
{ "first_item": { "path": "items[0].name", "array_mode": "first" } }
Array modes: first, last, flatten
Modes
| Mode | Reads | Writes | Source of Truth |
|---|---|---|---|
| Native | Rekor | Rekor | Rekor (default) |
| Proxy | External API | External API | External system |
| Sync In (planned) | Rekor | External API | External system |
| Native + Sync Out (planned) | Rekor | Rekor → External | Rekor |
Multiple Sources
A single collection can have multiple external sources. The external_source field on each record determines which backend handles it. Records without an external_source use Rekor's native storage.
Deterministic IDs
Proxied records get stable Rekor IDs derived from (collection, external_source, external_id). This means proxied records can participate in relationships — linking a Stripe invoice to an internal project works seamlessly.
Security
Source secrets are stored securely and never returned in API responses. Only used at request time to authenticate with the external API.