Browse documentation

Type to search the documentation. Press Esc to close.

How do I keep Scribble contacts in sync with my system?

For developers

Use POST /api/v1/contacts with an external_id from your system. Scribble upserts on that ID, so a nightly job will not create a fifth copy of the same person on the fifth night. Send the complete record every time: an update writes every field, so anything you leave out is set to null.

On this page

Verified against the live API: a second POST for the same external_id omitting birthday, work_anniversary and address.line2 returned the contact with all three set to null.

#A sync that behaves

  1. Create a key with only the contact scopes

    Integrations → New key, ticking contacts:read and contacts:write and nothing else. A sync job has no business being able to spend credits.

  2. Choose a stable external ID

    Use your system's primary key, not the email address. People change email addresses and share inboxes; a CRM record ID does not move.

  3. Push the complete record

    Every field your system knows about, every time.

    Upsert one contact
    curl -X POST https://scribblecards.com/api/v1/contacts \
      -H "Authorization: Bearer sk_live_..." \
      -H "Content-Type: application/json" \
      -d '{
        "external_id": "crm-8812",
        "first_name": "Priya",
        "last_name": "Raman",
        "email": "priya@northgate.example",
        "company": "Northgate",
        "job_title": "Head of People",
        "birthday": "1990-03-14",
        "work_anniversary": "2021-06-01",
        "address": {
          "line1": "1 Fifth Avenue",
          "line2": "Apt 12B",
          "city": "New York",
          "state": "NY",
          "zip": "10003"
        }
      }'

    You’ll know it worked when 201 the first time, 200 on every subsequent sync for the same external_id, with the same contact id in the body.

  4. Rate-limit yourself

    A key is limited to 120 requests a minute by default. A 10,000-contact sync at that rate takes about 84 minutes; either spread it out or ask us to raise the limit. A 429 carries a Retry-After header in seconds — honour it.

  5. Reconcile, do not assume

    Read back with GET /api/v1/contacts?external_id=... after the first few writes and compare against your source. It is much cheaper to find a mapping bug on record 5 than on record 5,000.

#What a sync cannot do

  • Delete contacts. The contacts:write scope explicitly cannot delete. Remove people from lists instead, or add them to the do-not-mail list if they must never be written to again.
  • Manage list membership. There is no list endpoint. Lists are managed in the app.
  • Verify addresses. Every address is stored as unverified. Scribble checks the shape of an address, not whether post arrives there. See address requirements.

#Common questions

What happens if I omit external_id?
Every call creates a new contact. There is no fallback matching on email, deliberately: two people who share an inbox would silently be merged into one, which is a worse failure than a duplicate.
How does Scribble split a single name field?
The first word becomes the first name and the rest becomes the last name. That is imperfect for some naming conventions, so send first_name and last_name separately when you have them.
Are birthdays stored with a year?
No. Send 1990-03-14 or 03-14; only the month and day are stored. Work anniversaries do keep the full date, because the year is what makes {{years}} work.

Last checked against the product on . Something wrong or missing? Tell us.