← Learn

Migrate from Attio to Relm in one agent run

Export your Attio CSVs, hand them to an AI agent along with a Relm API key, and the agent does the rest: recreates your pipeline, registers your custom attributes as fields, and batch-loads every person, company, deal and note. No manual re-entry, no import wizard.

This guide walks through the whole move: what to export from Attio, how each Attio object and attribute maps onto Relm, the exact API calls an agent makes, and how to verify the result before you switch over. Everything here works over plain REST, but the intended path is simpler - you paste a prompt into Claude or any MCP client and supervise.

Why teams move from Attio to Relm

Attio deserves its reputation. Its data model - objects with typed attributes, records, lists with list-specific attributes - is genuinely flexible, and the workspace UI is one of the best in the category. If humans are the ones working your CRM every day, Attio is a strong choice, and nothing in this guide argues otherwise.

The reason to move is a change in who operates the CRM. Attio is built around a human workspace: views, lists, collaborative notes, per-seat pricing. Relm inverts that. The REST API and the native MCP server are the product, and the dashboard is a thin layer on top. The practical differences for an agent-driven setup:

Step 1: export your data from Attio

Attio exports CSV per object. Open a view of People, then Companies, then Deals, and use the view's export option to download each as a CSV - columns are named after your attributes, including any custom ones. If your deals live on a list (the common Attio pattern, with a status attribute for stage), export from the list view so the stage and any list-specific attributes ride along.

Two things do not travel in record CSVs: notes and tasks. If the history matters, pull them from Attio's REST API (GET /v2/notes and GET /v2/tasks on api.attio.com) into a JSON or CSV file. Each note carries the record it is attached to and a created timestamp - both survive the move, as you will see below.

Step 2: the field mapping

Relm's model is deliberately small: contacts, companies, deals and activities, plus custom fields for everything else. Attio's standard attributes map cleanly; custom attributes become Relm custom fields, registered once and typed.

AttioRelmNotes
Company → Namecompany.nameRequired.
Company → Domainscompany.domainAttio allows several; take the primary one.
Company → Description, Categories, Employee rangecompany.custom_fields.*Register via POST /v1/fields.
Person → Namecontact.first_name / last_nameSplit on the first space if exported as one column.
Person → Email addressescontact.emailPrimary address; email is optional in Relm, so email-less people still import.
Person → Phone numberscontact.phone
Person → LinkedIncontact.linkedin_url
Person → Job titlecontact.custom_fields.job_titleCustom text field.
Person → Companycontact.company_idResolve by the company's domain after companies are loaded.
Deal → Namedeal.titleRequired.
Deal → Valuedeal.value_cents + currencyInteger minor units: $12,000 becomes 1200000.
Deal → Stage (list status)deal.stage in a mirrored pipelineStages recreated 1:1, see below.
Deal → Associated company / peopledeal.company_id / primary_contact_id
Deal → Ownerdeal.custom_fields.ownerCustom text field.
Note / Task (via Attio API)activity with occurred_atType note; the original timestamp is preserved.

Step 3: one-time setup

Before loading records, the agent makes a handful of idempotent setup calls: a pipeline whose stages are exactly your Attio stages, and one field registration per custom attribute. Attio's default deal stages are Lead, In Progress, Won and Lost - if you customized them, map yours 1:1 instead.

# mirror the Attio deal stages as a Relm pipeline
curl -X POST https://api.relmcrm.com/v1/pipelines \
  -H "Authorization: Bearer relm_test_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Sales","stages":["lead","in_progress","won","lost"]}'

# register custom fields once, then send values under custom_fields
curl -X POST https://api.relmcrm.com/v1/fields \
  -H "Authorization: Bearer relm_test_..." \
  -H "Content-Type: application/json" \
  -d '{"object":"contact","key":"job_title","data_type":"text"}'

Note the relm_test_ key: rehearse the entire import in test mode first. It is free, does not count against any quota, and the data never touches your live workspace.

Step 4: load in batches of 100

POST /v1/batch takes up to 100 operations per call and returns a per-operation result array - one bad row does not fail the batch. Records get server-assigned IDs, so load in dependency order across batches: companies first, then contacts referencing company IDs, then deals, then activities. Within a single batch, operations cannot reference each other's new IDs - the cmp_ and deal_ IDs in the example below came from earlier batches. Each operation counts against your monthly quota exactly like an individual request - batching saves round-trips, not quota.

curl -X POST https://api.relmcrm.com/v1/batch \
  -H "Authorization: Bearer relm_test_..." \
  -H "Content-Type: application/json" \
  -d '{"operations":[
    {"object":"contact","data":{
      "first_name":"Maya","last_name":"Chen",
      "email":"[email protected]",
      "linkedin_url":"https://linkedin.com/in/mayachen",
      "company_id":"cmp_9f2k1x7q",
      "custom_fields":{"job_title":"Head of Operations"}}},
    {"object":"deal","data":{
      "title":"Northwind Labs - annual",
      "pipeline":"sales","stage":"in_progress",
      "value_cents":1200000,"currency":"USD",
      "company_id":"cmp_9f2k1x7q"}},
    {"object":"activity","data":{
      "type":"note","body":"Intro call went well; wants Q3 rollout.",
      "deal_id":"deal_7h3m2v8s",
      "occurred_at":"2025-11-14T09:30:00Z"}}
  ]}'

{ "object": "batch", "count": 3, "succeeded": 3, "failed": 0, "results": [...] }

The occurred_at on that note is doing real work: it backdates the activity to when it actually happened in Attio, so your timeline survives the move instead of collapsing into one import day.

Or skip the curl: hand it to your agent

The path most people take. Point any MCP client - Claude, Cursor, anything that speaks the protocol - at https://api.relmcrm.com/mcp with your key (setup details in the docs and the agent hub), attach the Attio CSVs, and say:

Import my Attio workspace into Relm from the attached CSVs
(people.csv, companies.csv, deals.csv, notes.json).

1. Call relm_describe_schema first.
2. Create a pipeline named "Sales" whose stages match the Stage
   column in deals.csv, in order.
3. Register custom fields for any column that is not a standard
   Relm field (job_title, owner, employee_range).
4. Load with relm_batch, 100 ops per call, in dependency order:
   companies, then people, then deals, then notes as activities
   with occurred_at set to each note's created date.
5. Skip nothing - people without an email are fine.
6. Report counts per object when done, and every failed row.

The agent discovers the whole contract from relm_describe_schema, and it self-corrects as it goes: an unknown stage or field comes back as a 422 with valid_options and the exact call to create it. This is the same read-the-schema-then-act loop described in what is a CRM for LLMs - migration is just its largest single workout.

Step 5: verify before you switch

Do not trust "done", verify it. Three checks, all cheap:

When the test-mode run checks out, repeat the exact same run with your relm_live_ key. One practical note on quota: the Free plan's 1,000 requests a month will cover a small workspace, but a real import belongs on Pro - each batch operation is one request, so 5,000 records plus verification fits well inside Pro's 100,000. On paid plans you can also set a hard spend cap so an oversized import stops cleanly instead of running up overage.

After the move

Migration is the entry point, not the destination. Once the data is in Relm, the interesting part starts: your agent works the CRM directly - logging calls, advancing deals, running follow-ups - over the same API it used for the import. How to give your AI agent a CRM covers that operating loop, and the API docs hold the full reference for every endpoint used above.

FAQ

How long does an Attio to Relm migration take?

For a typical workspace of a few hundred to a few thousand records, one agent run of a few minutes. POST /v1/batch accepts up to 100 operations per call with per-op results, so a 2,000-record workspace is about 20 batch calls plus one-time setup for the pipeline and custom fields.

Do I need to write code to migrate from Attio?

No. Export CSVs from Attio, then give any MCP client - Claude, ChatGPT, Cursor - the files plus a Relm API key pointed at https://api.relmcrm.com/mcp. The agent reads the live schema with relm_describe_schema, registers custom fields, creates the pipeline, and loads everything with relm_batch. The curl examples in this guide are for people who prefer scripts.

What happens to my Attio deal stages?

They are recreated 1:1. One call to POST /v1/pipelines creates a named pipeline whose ordered stages are exactly your Attio stages - for example lead, in_progress, won, lost - and every imported deal is placed in the stage it held in Attio.

What about custom attributes I created in Attio?

Register each one once with POST /v1/fields (object, key, data_type), then send values under custom_fields on every record. Types are enforced - a number field rejects text - so bad rows surface during the import instead of later.

Will re-running the import create duplicates?

For contacts, no - creating a contact with an email that already exists returns a 409 conflict that includes the existing record, so re-imported people are caught. Companies, deals and activities have no server-side dedupe, so do not blindly replay those batches - re-run only the rows that failed, which each batch's per-operation results identify exactly. An Idempotency-Key header protects single-record POSTs against network retries; POST /v1/batch does not take one.

How much does the migration cost?

Rehearsing in test mode (relm_test_ key) is free and unlimited. On live keys every batch operation counts as one request: the Free plan includes 1,000 requests a month with no card, Pro is $29/mo for 100,000, Scale is $249/mo for 2,000,000. A 5,000-record import fits comfortably in Pro's first month.

Ready to move?

Mint a free test key, hand your agent the CSVs, and rehearse the whole migration today. See pricing.

Start free →