Skip to main content
POST
Add a contact
Adds a contact to one of your entities. Omit upstreamDownstreamAssociationId for an agency-wide contact that every one of your markets can see; supply it to confine the contact to one market relationship.

Email addresses are unique across Turris, and this is the part to read

Contact email is unique platform-wide, not per agency. So an address you add may already belong to a contact another agency introduced first. When that happens, this endpoint attaches a new scope for your entity to the existing contact and returns it as normal. The response is indistinguishable from having created a fresh contact: it shows only your own scopes, and it reflects the name you sent.
That indistinguishability is deliberate and it is the reason this endpoint does not return 409 for a known address. A 409, or a response carrying somebody elseโ€™s stored name, would let you test any email against the platform and learn whose contact it is. We would rather the create tell you nothing than tell you that.
Two consequences worth planning for:

Your name is yours only

On a shared record the stored firstName and lastName stay as the first agency recorded them โ€” a create must not rename a record two agencies share. You will not see theirs; the response echoes what you sent. Treat it as authoritative for your scopes, not as a read of the database.

A duplicate scope is a 409

Adding a scope you already hold, for the same entity and market, returns 409. That is a duplicate rather than a disclosure, and it is actionable.
Send an Idempotency-Key header. See Idempotency.

Headers

idempotency-key
string

UUID to ensure idempotent request processing

Example:

"550e8400-e29b-41d4-a716-446655440000"

x-idempotency-key
string

Alternative UUID header for idempotent request processing

Example:

"550e8400-e29b-41d4-a716-446655440000"

Body

application/json
firstName
string
required

Given name. Stored only when this email is new to Turris; on an address the platform already knows, the existing record keeps its name and this value is echoed back to you unchanged.

Example:

"Jon"

lastName
string
required

Surname. Stored only when this email is new to Turris; on an address the platform already knows, the existing record keeps its name and this value is echoed back to you unchanged.

Example:

"Doe"

email
string
required

Email address. Unique across Turris and matched case-insensitively, so an address already known to the platform is attached to your agency rather than duplicated.

Example:

"example@test.com"

downstreamEntityId
string

Which of your entities this contact belongs to. Defaults to your own organization.

Example:

"6610b3d2c2e0a51b8c0d1f02"

upstreamDownstreamAssociationId
string

Confine the contact to one market relationship. Omit for an agency-wide contact, which every one of your markets can see.

Example:

"6627f1a9c2e0a51b8c0d4e3a"

businessRoles
enum<string>[]

Business roles this contact holds within the scope being created.

Available options:
Compliance Officer,
Principal Owner,
Account Manager,
Finance Manager,
Support Staff,
Contract Signatory,
Accounts Payable,
Policy Maintenance
Example:
isPrimary
boolean

Whether this is the primary contact for the scope being created.

Example:

false

Response

The contact, with your scopes

data
object
required
requestId
string
required

Unique request identifier

Example:

"dev-2c5e7cf2-9acf-4c8c-ab2f-b81f39d775a8"

timestamp
string
required

Response timestamp

Example:

"2025-11-12T20:49:03.293Z"