Skip to content

Send a record

Send a record whenever it’s created or changed in your system. Samesake works out whether it’s new.

POST /api/v1/records sends one record. If the source has no record with this sourceRecordId, Samesake creates one. If it has, Samesake updates it. So this is the call to use whenever a record is created or changed: you don’t need to know whether Samesake has seen it before.

Terminal window
curl -i -X POST https://app.samesake.co.uk/api/v1/records \
-H "X-Api-Key: mk_abcd1234_0123456789abcdefghjkmnpqrstvwxyz" \
-H "Content-Type: application/json" \
-d '{
"sourceRecordId": "CRM-10043",
"title": "Mr",
"firstName": "Tom",
"lastName": "Fletcher",
"email": "tom.fletcher@example.com",
"dateOfBirth": "12/09/1979",
"addressLine1": "7 Alder Court",
"addressLine2": "Stockport",
"postcode": "SK4 2DD",
"phones": ["07700 900456"]
}'

Try it in the API reference

The response says which it was:

Status Meaning Body
201 Created The source had no record with this sourceRecordId. A Location header points to the new record. {"recordId": "rec_..."}
200 OK The record already existed. It was updated, or already had these details. {"recordId": "rec_..."}

The body is the same either way: Samesake’s recordId for the record. It never changes, so you can store it beside your own ID. The single-record call doesn’t say whether a 200 changed anything. A batch does: it reports Created, Updated or Unchanged for every record.

Each request replaces everything Samesake holds for the record. A field you leave out, or send as null, is cleared. So if Tom’s email address is in your system, send it every time you send Tom, not just when it changes.

There’s no way to send only the changed fields. That keeps the API simple, and means a retry or a repeat can’t go wrong: sending the same record twice leaves it as it was, and Samesake answers Unchanged (in a batch) when nothing differs.

Only sourceRecordId is required. The API never rejects a value for being badly formed: a date, phone number or postcode that Samesake can’t read is kept exactly as you sent it, and isn’t used for matching. Apart from a body that isn’t valid JSON, the only thing it refuses is a field that goes over a limit in the table.

Field Limit What to send
sourceRecordId Required, 1 to 100 characters Your ID for the record in this source, such as the contact ID. Spaces at either end are removed, after the length is checked. Capital letters matter: abc and ABC are two records.
title 200 characters Mr, Mrs, Ms, Miss, Mx, Dr, Prof, Rev, and similar. Another title is kept, but isn’t recognised.
firstName 200 characters First name.
lastName 200 characters Last name.
email 200 characters Email address.
dateOfBirth 200 characters Best as yyyy-mm-dd. Other formats are read too.
addressLine1 200 characters The house number or name, and the street.
addressLine2 200 characters The next line, such as the town.
postcode 200 characters A UK postcode, with or without the space.
phones 10 phone numbers, each 200 characters A list of UK phone numbers, mobile or landline, in any usual format.

Send a field only if you know it. Leave it out when you don’t, rather than sending a placeholder such as unknown, n/a or 01/01/1970. Samesake recognises many placeholders and ignores them, but a field left out is clearer.

Samesake matches on a cleaned-up copy of what you send, so capital letters, accents, extra spaces and punctuation other than hyphens and apostrophes don’t matter. A Jr, Sr, II, III or IV on the end of a name is read as a generational suffix, and helps keep a father and son apart.

Put the house number or name and the street in addressLine1, and the rest in addressLine2. Common abbreviations such as St, Rd and Ave are read as street, road and avenue. If your system keeps the house number and the street in separate fields, join them.

An email address is lower-cased, and has to look like one: a single @, with a dot in the part after it, no spaces and no dot at the end. One that doesn’t is kept as sent, and isn’t used for matching.

Two kinds of address are recognised. A shared mailbox such as info@, sales@ or support@ counts for little as evidence, because many people use it. A placeholder such as test@, none@ or noemail@ isn’t used at all.

Send the date of birth as yyyy-mm-dd, for example 1986-04-03. These forms are read too, and always day first: 03/04/1986 is 3 April.

Form Example
yyyy-mm-dd, yyyy-m-d, yyyy/mm/dd 1986-04-03, 1986-4-3, 1986/04/03
dd/mm/yyyy, d/m/yyyy 03/04/1986, 3/4/1986
dd-mm-yyyy, d-m-yyyy 03-04-1986, 3-4-1986
dd.mm.yyyy, d.m.yyyy 03.04.1986, 3.4.1986
dd/mm/yy, d/m/yy, dd-mm-yy, d-m-yy 03/04/86, 3-4-86

A time after a ten-character date, as in 1986-04-03T00:00:00 or 03/04/1986 00:00, is dropped. With a two-digit year, a date that would fall in the future is taken to be in the last century, so 03/04/86 is 1986. Send four digits where you can: 03/04/26 reads as 2026.

A date isn’t used for matching if it isn’t one of these forms, isn’t a real date (such as 30 February), is before 1900, is in the future, or is one of the placeholders 01/01/1900, 01/01/1901 and 01/01/1970.

Send phone numbers as a list, in any usual UK format. Spaces, brackets and dashes are ignored, and all of these are read as the same mobile number:

07700 900123
+44 7700 900123
0044 7700 900123
447700900123
7700 900123

A landline works the same way: 0161 496 0123, (0161) 496 0123, +44 161 496 0123 or +44 (0)161 496 0123.

Samesake uses a number for matching if it’s a UK mobile (starting 07) or a UK landline (starting 01, 02 or 03). It keeps, but doesn’t use, a number that isn’t one of those: personal numbers and pagers (070 and 076), any other kind of number, such as 05, 08 and 09 numbers, numbers written with another country’s code, numbers of the wrong length, and obvious dummies such as 01234 567890, a number with only one or two different digits after the first 0, or one that contains 123456789 or 987654321. Leave extensions out: any digits after the number make it unreadable.

Send a UK postcode with or without the space, in any case: M20 6RT, m206rt. The letter O in a place where only a digit fits, and the digit 1 where only a letter fits, are corrected. A postcode that isn’t a valid UK postcode isn’t used for matching.

PUT updates a record Samesake already has, by your ID or by Samesake’s. Most integrations don’t need it, because POST does the same and also creates new records. Use PUT when a record Samesake doesn’t have should be an error rather than quietly created, or when you only have Samesake’s recordId:

Terminal window
curl -i -X PUT https://app.samesake.co.uk/api/v1/records/by-source-id/CRM-10042 \
-H "X-Api-Key: mk_abcd1234_0123456789abcdefghjkmnpqrstvwxyz" \
-H "Content-Type: application/json" \
-d '{
"title": "Ms",
"firstName": "Priya",
"lastName": "Sharma",
"email": "p.sharma@example.com",
"dateOfBirth": "1986-04-03",
"addressLine1": "3 Willow Court",
"addressLine2": "Stockport",
"postcode": "SK4 2DD",
"phones": ["07700 900123"]
}'

Try it in the API reference

To use Samesake’s ID, put it in the path instead: PUT /api/v1/records/rec_7k2m9xq4ht3b.

It works like POST, with two differences. The body has no sourceRecordId, because the path names the record (one sent anyway is ignored). And PUT never creates a record: if the source has no record with that ID, the answer is 404 Not Found. It answers 200 OK with the recordId.

An ID that contains a / can’t be used in the by-source-id paths: an encoded slash (%2F) isn’t decoded, so Samesake looks for an ID with the %2F in it and doesn’t find your record. Use POST with the ID in the body, or put Samesake’s recordId in the path. Encode other awkward characters, such as spaces, as %20.

GET returns a record as Samesake holds it, by your ID or by Samesake’s:

Terminal window
curl -i https://app.samesake.co.uk/api/v1/records/rec_7k2m9xq4ht3b \
-H "X-Api-Key: mk_abcd1234_0123456789abcdefghjkmnpqrstvwxyz"

Try it in the API reference

You get the details as you sent them, personId, deleted, and linkedRecords: the recordId, source code, sourceRecordId and link type of every record matched to this one, from any source, with IDs only, not their details. Auto means Samesake linked them itself, and Confirmed means a reviewer did.

personId is null until matching has looked at the record. A deleted record is still returned, with deleted set to true and its details cleared. A record that isn’t in this source is a 404.

  • A record was created or changed in your system: POST /api/v1/records, or a batch for many.
  • You want to update a record only if Samesake already has it: PUT, as above.
  • A record was deleted in your system: delete it.
  • Your system can’t tell you about deletions: send a snapshot from time to time as well.
  • You have a file, and no developer: an admin can upload a CSV file.

Samesake shows when it last heard from each source, and can warn an admin if nothing arrives for a number of days that you choose. Set it with Warn after on the source’s row under Admin, then Sources: from 1 to 90 days.