Canonical
Attio
Push enriched Orakel company records into Attio CRM records.
Overview
Attio is a records-first CRM. Orakel pushes company records (firmographics, financials, roles, domains, technographics, TBR licenses) into an Attio workspace, upserting on org_number and falling back to domain match.
The integration is push-based: create a Destination of type attio with an Attio API token, then call POST /api/push/:destinationName with a list of Norwegian org numbers. Destination config is encrypted at rest (AES-256-GCM).
There is a separate webhook path (POST /api/webhooks/attio) that triggers enrichment when a record is created or updated inside Attio — see Gotchas.
Setup
- Create an Attio API token — Attio Settings → Developers → Create access token. Scope it to your workspace with read/write on the
companiesobject. - Create the destination:
curl -X POST https://orakel.cloud/api/destinations \ -H "Authorization: Bearer $ORAKEL_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "attio-prod", "type": "attio", "config": { "apiKey": "sk_live_...", "fieldMappings": { "naceDescription1": "nace_description", "revenue": "revenue" } } }' - Trigger a push:
curl -X POST https://orakel.cloud/api/push/attio-prod \ -H "Authorization: Bearer $ORAKEL_KEY" \ -H "Content-Type: application/json" \ -d '{"orgNumbers": ["923609016"]}'
Field mapping
Two categories of fields are written to Attio:
Built-in Attio slugs (always written, no mapping required)
| Orakel field | Attio slug | Shape |
|---|---|---|
foundingDate |
foundation_date |
[{ value: "YYYY-MM-DD" }] |
businessAddress* |
primary_location |
[{ line_1, locality, region, postcode, country_code, ... }] |
employeeCount |
employee_range |
[{ option: "1-10" | "11-50" | "51-250" | ... }] |
linkedinHandle |
linkedin |
[{ value: "https://linkedin.com/company/<handle>" }] |
facebookHandle |
facebook |
[{ value: "https://facebook.com/<handle>" }] |
instagramHandle |
instagram |
[{ value: "https://instagram.com/<handle>" }] |
twitterHandle |
twitter |
[{ value: "https://x.com/<handle>" }] |
Custom slugs (written only if listed in config.fieldMappings)
Keys on the left are Orakel field names; values on the right are your workspace's Attio slugs. The adapter exposes: orgNumber, country, name, orgFormCode, naceCode1, naceDescription1, employeeCount, businessAddressMuni, businessAddressMuniNo, countyCode, website, phone, sectorDescription, isBankrupt, isBeingDissolved, parentOrgNumber, primaryDomain, domainConfidence, enrichedDomains, linkedinHandle, facebookHandle, instagramHandle, twitterHandle, technologies, revenue, netResult, operatingResult, totalAssets, totalEquity, totalDebt, ceo, boardChair, boardMembers, auditor. If the company has a TBR skjenkebevilling, the adapter also exposes licenseType, licenseVenueName, licenseMunicipality, licenseValidFrom, licenseValidTo, hasSpirits, hasWine, hasBeer, licenseCount.
Mapping any field to Attio's built-in domains slug is handled specially: strings get stripped and wrapped, arrays pass through, and enrichedDomains is preferred over website when richer.
Configuration
{
"apiKey": "sk_live_...",
"fieldMappings": {
"orgNumber": "org_number",
"revenue": "revenue",
"ceo": "ceo_name",
"primaryDomain": "domains"
}
}apiKey— Attio access token. Required.fieldMappings— map of Orakel field → Attio slug. Optional; omit to use only the built-in slugs above.
Push behavior
- Matching: search for an existing record by
org_number. If none, fall back todomains. If still none, create. - On match:
PATCHthe existing record. Thenameattribute is stripped from the update payload to preserve brand names. - On no match:
POSTa new record. - Per-company result is tallied into
created,updated,failedcounts, returned byPOST /api/push/:destinationName.
Gotchas
- Financials: use Currency type in Attio for
revenue,netResult,operatingResult,totalAssets,totalEquity,totalDebt. Text type will round-trip to string and break sorting. - Built-in fields use array-of-objects shape:
[{ value: "..." }]for text/date,[{ option: "..." }]for select,[{ line_1, ... }]for location. The adapter handles this; if you copy the mapping elsewhere, respect the shape. - Webhook envelope: Attio sends webhooks wrapped in
{ webhook_id, events: [...] }, not flat single events. The Orakel webhook handler iteratesevents[]and dispatches per entry. - No webhook delivery history in Attio API: check Attio Settings → Developers → Webhooks for failures.
- Token scope: a workspace-scoped token cannot reach objects in other workspaces. One destination per workspace.
Related
- Destinations endpoint — CRUD for destinations and push trigger
- Brreg — primary source for firmographics and roles
- Regnskapsregisteret — source for the financial fields