You can upsert data with POST and the Prefer: resolution=merge-duplicates header:

curl "https://integration.getmateo.com/api/v1/contact" \
  -X POST -H "Content-Type: application/json" \
  -H "Prefer: resolution=merge-duplicates" \
  -d '{ "id": 1, full_name": "Max Mustermann" }'

By default, upsert operates based on the primary key columns, you must specify all of them. You can also choose to ignore the duplicates with Prefer: resolution=ignore-duplicates.

On Conflict

By specifying the on_conflict query parameter, you can make upsert work on a column(s) that has a UNIQUE constraint.

curl "https://integration.getmateo.com/api/v1/contact?on_conflict=external_id" \
  -X POST -H "Content-Type: application/json" \
  -H "Prefer: resolution=merge-duplicates" \
  -d '{ "external_id": 1, full_name": "Max Mustermann" }'

PUT

You can also upsert data with PUT:

curl "https://integration.getmateo.com/api/v1/contact?id=eq.123" \
  -X PUT -H "Content-Type: application/json" \
  -d '{ "id": 123, "full_name": "Max Mustermann" }'

All the columns must be specified in the request body, including the primary key column(s).

Response

If the data was inserted, the response status code will be 201 Created. If the data was updated, the response status code will be 200 OK.

The response body will be empty by default, but you can add a select query parameter to select the columns that should be returned:

curl "https://integration.getmateo.com/api/v1/contact?id=eq.123&select=id,full_name" \
  -X PUT -H "Content-Type: application/json" \
  -d '{ "id": 123, "full_name": "Max Mustermann" }'
{
  "id": 1234,
  "full_name": "Max Mustermann"
}