Identity: contacts
Contacts with their tier and switchboard
Section titled “Contacts with their tier and switchboard”GET /v1/identities/{slug}/contacts · operation listContacts
Requires the batondeck:contacts:read permission (action contact:read).
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
status |
query | “active” \ | “pending_in” \ | “pending_out” \ |
Responses
| Status | Meaning |
|---|---|
| 200 | Contacts with their tier and switchboard |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
200 response schema
{ "type": "object", "properties": { "contacts": { "type": "array", "items": { "type": "object", "properties": { "fingerprint": { "type": "string" }, "display_name": { "type": "string" }, "status": { "type": "string", "enum": [ "active", "pending_in", "pending_out", "blocked" ] }, "preset": { "type": "string" }, "permissions": { "type": "array", "items": { "type": "string" } }, "trust_flag": { "type": "string" }, "petname": { "type": "string" }, "last_seen_at": { "type": "number" }, "created_at": { "type": "number" }, "endpoint": { "type": "string" }, "leaf": { "type": "string" }, "root_cert": { "type": "string" }, "address_claim": { "anyOf": [ { "type": "object", "properties": { "root": { "type": "string" }, "name": { "type": "string" } }, "required": [ "root", "name" ], "additionalProperties": false }, { "type": "null" } ] }, "acceptance_unheard_since": { "anyOf": [ { "type": "number" }, { "type": "null" } ] } }, "required": [ "fingerprint", "display_name", "status", "preset", "permissions", "trust_flag", "petname", "last_seen_at", "created_at", "endpoint", "address_claim", "acceptance_unheard_since" ], "additionalProperties": false } } }, "required": [ "contacts" ], "additionalProperties": false}curl -X GET 'https://api.batondeck.com/v1/identities/:slug/contacts' \ -H "Authorization: Bearer $BATONDECK_API_KEY"Ask the holder of a contact card to be a contact of this identity (SPEC §5.2, the manual flow)
Section titled “Ask the holder of a contact card to be a contact of this identity (SPEC §5.2, the manual flow)”POST /v1/identities/{slug}/contacts · operation requestContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes |
Request body (application/json)
| Field | Type | Required | Notes |
|---|---|---|---|
card |
string | yes | ≥ 1 chars, ≤ 16384 chars |
note |
string | ≤ 1024 chars |
Request schema
{ "type": "object", "properties": { "card": { "type": "string", "minLength": 1, "maxLength": 16384 }, "note": { "type": "string", "maxLength": 1024 } }, "required": [ "card" ], "additionalProperties": false}Responses
| Status | Meaning |
|---|---|
| 201 | Ask the holder of a contact card to be a contact of this identity (SPEC §5.2, the manual flow) |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
201 response schema
{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "pending", "active" ] }, "contact": { "type": "object", "properties": { "fingerprint": { "type": "string" }, "endpoint": { "type": "string" }, "display_name": { "type": "string" } }, "required": [ "fingerprint", "endpoint", "display_name" ], "additionalProperties": false } }, "required": [ "status", "contact" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts' \ -H "Authorization: Bearer $BATONDECK_API_KEY" \ -H 'content-type: application/json' \ -d @body.jsonSet what a contact may do: a preset, or the switches one by one
Section titled “Set what a contact may do: a preset, or the switches one by one”PATCH /v1/identities/{slug}/contacts/{fingerprint} · operation updateContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Request body (application/json)
| Field | Type | Required | Notes |
|---|---|---|---|
preset |
“basic” \ | “colleague” \ | “close” \ |
permissions |
array of string |
Request schema
{ "type": "object", "properties": { "preset": { "type": "string", "enum": [ "basic", "colleague", "close", "muted" ] }, "permissions": { "maxItems": 64, "type": "array", "items": { "type": "string", "maxLength": 96 } } }, "additionalProperties": false}Responses
| Status | Meaning |
|---|---|
| 200 | Set what a contact may do: a preset, or the switches one by one |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
200 response schema
{ "type": "object", "properties": { "contact": { "type": "object", "properties": { "fingerprint": { "type": "string" }, "display_name": { "type": "string" }, "status": { "type": "string", "enum": [ "active", "pending_in", "pending_out", "blocked" ] }, "preset": { "type": "string" }, "permissions": { "type": "array", "items": { "type": "string" } }, "trust_flag": { "type": "string" }, "petname": { "type": "string" }, "last_seen_at": { "type": "number" }, "created_at": { "type": "number" }, "endpoint": { "type": "string" }, "leaf": { "type": "string" }, "root_cert": { "type": "string" }, "address_claim": { "anyOf": [ { "type": "object", "properties": { "root": { "type": "string" }, "name": { "type": "string" } }, "required": [ "root", "name" ], "additionalProperties": false }, { "type": "null" } ] }, "acceptance_unheard_since": { "anyOf": [ { "type": "number" }, { "type": "null" } ] } }, "required": [ "fingerprint", "display_name", "status", "preset", "permissions", "trust_flag", "petname", "last_seen_at", "created_at", "endpoint", "address_claim", "acceptance_unheard_since" ], "additionalProperties": false } }, "required": [ "contact" ], "additionalProperties": false}curl -X PATCH 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint' \ -H "Authorization: Bearer $BATONDECK_API_KEY" \ -H 'content-type: application/json' \ -d @body.jsonRemove a contact: the pin goes on both sides and they are told (SPEC §5.3)
Section titled “Remove a contact: the pin goes on both sides and they are told (SPEC §5.3)”DELETE /v1/identities/{slug}/contacts/{fingerprint} · operation removeContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Responses
| Status | Meaning |
|---|---|
| 200 | Remove a contact: the pin goes on both sides and they are told (SPEC §5.3) |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
200 response schema
{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "removed" ] }, "fingerprint": { "type": "string" }, "notified": { "type": "boolean" } }, "required": [ "status", "fingerprint", "notified" ], "additionalProperties": false}curl -X DELETE 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint' \ -H "Authorization: Bearer $BATONDECK_API_KEY"Approve a contact request and set the preset it starts on
Section titled “Approve a contact request and set the preset it starts on”POST /v1/identities/{slug}/contacts/{fingerprint}/approve · operation approveContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Accepts an Idempotency-Key header. A repeat within 24 hours returns the first answer; the same key with different arguments is refused with idempotency_mismatch.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes | |
Idempotency-Key |
header | string | Repeat this value to retry the call without repeating its effect. |
Request body (application/json)
| Field | Type | Required | Notes |
|---|---|---|---|
preset |
“basic” \ | “colleague” \ | “close” \ |
Request schema
{ "type": "object", "properties": { "preset": { "default": "basic", "type": "string", "enum": [ "basic", "colleague", "close", "muted" ] } }, "required": [ "preset" ], "additionalProperties": false}Responses
| Status | Meaning |
|---|---|
| 200 | Approve a contact request and set the preset it starts on |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 422 | That Idempotency-Key was used with different arguments. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
200 response schema
{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "approved" ] }, "fingerprint": { "type": "string" }, "preset": { "type": "string" }, "notified": { "type": "boolean" } }, "required": [ "status", "fingerprint", "preset", "notified" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/approve' \ -H "Authorization: Bearer $BATONDECK_API_KEY" \ -H 'content-type: application/json' \ -d @body.jsonReject a contact request: they are blocked, so they cannot knock again, and they are told (SPEC §5.1)
Section titled “Reject a contact request: they are blocked, so they cannot knock again, and they are told (SPEC §5.1)”POST /v1/identities/{slug}/contacts/{fingerprint}/reject · operation rejectContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Accepts an Idempotency-Key header. A repeat within 24 hours returns the first answer; the same key with different arguments is refused with idempotency_mismatch.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes | |
Idempotency-Key |
header | string | Repeat this value to retry the call without repeating its effect. |
Responses
| Status | Meaning |
|---|---|
| 200 | Reject a contact request: they are blocked, so they cannot knock again, and they are told (SPEC §5.1) |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 422 | That Idempotency-Key was used with different arguments. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
200 response schema
{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "rejected" ] }, "fingerprint": { "type": "string" }, "notified": { "type": "boolean" } }, "required": [ "status", "fingerprint", "notified" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/reject' \ -H "Authorization: Bearer $BATONDECK_API_KEY"Tell an active contact again that we accepted them (SPEC §5.1), when the approval did not reach them
Section titled “Tell an active contact again that we accepted them (SPEC §5.1), when the approval did not reach them”POST /v1/identities/{slug}/contacts/{fingerprint}/tell-accepted · operation notifyAcceptance
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Accepts an Idempotency-Key header. A repeat within 24 hours returns the first answer; the same key with different arguments is refused with idempotency_mismatch.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes | |
Idempotency-Key |
header | string | Repeat this value to retry the call without repeating its effect. |
Responses
| Status | Meaning |
|---|---|
| 200 | Tell an active contact again that we accepted them (SPEC §5.1), when the approval did not reach them |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 422 | That Idempotency-Key was used with different arguments. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
200 response schema
{ "type": "object", "properties": { "fingerprint": { "type": "string" }, "notified": { "type": "boolean" }, "refusal": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "fingerprint", "notified", "refusal" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/tell-accepted' \ -H "Authorization: Bearer $BATONDECK_API_KEY"The tools a contact offers us, asked of them over the sealed handshake
Section titled “The tools a contact offers us, asked of them over the sealed handshake”GET /v1/identities/{slug}/contacts/{fingerprint}/tools · operation listContactTools
Requires the batondeck:contacts:read permission (action contact:read).
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Responses
| Status | Meaning |
|---|---|
| 200 | The tools a contact offers us, asked of them over the sealed handshake |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
200 response schema
{ "type": "object", "properties": { "tools": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "input_schema": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } }, "required": [ "name", "description", "input_schema" ], "additionalProperties": false } } }, "required": [ "tools" ], "additionalProperties": false}curl -X GET 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/tools' \ -H "Authorization: Bearer $BATONDECK_API_KEY"Call one of a contact’s tools as this identity (SPEC §5.4)
Section titled “Call one of a contact’s tools as this identity (SPEC §5.4)”POST /v1/identities/{slug}/contacts/{fingerprint}/call · operation callContactTool
Requires the batondeck:messages:send permission (action message:send).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Request body (application/json)
| Field | Type | Required | Notes |
|---|---|---|---|
tool |
string | yes | ≥ 1 chars |
arguments |
object |
Request schema
{ "type": "object", "properties": { "tool": { "type": "string", "minLength": 1 }, "arguments": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } }, "required": [ "tool" ], "additionalProperties": false}Responses
| Status | Meaning |
|---|---|
| 200 | Call one of a contact’s tools as this identity (SPEC §5.4) |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
200 response schema
{ "type": "object", "properties": { "ok": { "type": "boolean" }, "result": {} }, "required": [ "ok", "result" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/call' \ -H "Authorization: Bearer $BATONDECK_API_KEY" \ -H 'content-type: application/json' \ -d @body.jsonBlock a contact; the block is silent to them (SPEC §5.5)
Section titled “Block a contact; the block is silent to them (SPEC §5.5)”POST /v1/identities/{slug}/contacts/{fingerprint}/block · operation blockContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Accepts an Idempotency-Key header. A repeat within 24 hours returns the first answer; the same key with different arguments is refused with idempotency_mismatch.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes | |
Idempotency-Key |
header | string | Repeat this value to retry the call without repeating its effect. |
Responses
| Status | Meaning |
|---|---|
| 200 | Block a contact; the block is silent to them (SPEC §5.5) |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 422 | That Idempotency-Key was used with different arguments. |
200 response schema
{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "blocked" ] }, "fingerprint": { "type": "string" } }, "required": [ "status", "fingerprint" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/block' \ -H "Authorization: Bearer $BATONDECK_API_KEY"Undo a block: a former contact returns to active as they were; a declined request is forgotten (SPEC §5)
Section titled “Undo a block: a former contact returns to active as they were; a declined request is forgotten (SPEC §5)”POST /v1/identities/{slug}/contacts/{fingerprint}/unblock · operation unblockContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Responses
| Status | Meaning |
|---|---|
| 200 | Undo a block: a former contact returns to active as they were; a declined request is forgotten (SPEC §5) |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
200 response schema
{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "active", "forgotten" ] }, "fingerprint": { "type": "string" } }, "required": [ "status", "fingerprint" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/unblock' \ -H "Authorization: Bearer $BATONDECK_API_KEY"The owner’s own private name for a contact
Section titled “The owner’s own private name for a contact”PATCH /v1/identities/{slug}/contacts/{fingerprint}/petname · operation setPetname
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Request body (application/json)
| Field | Type | Required | Notes |
|---|---|---|---|
petname |
string | yes | ≤ 64 chars |
Request schema
{ "type": "object", "properties": { "petname": { "type": "string", "maxLength": 64 } }, "required": [ "petname" ], "additionalProperties": false}Responses
| Status | Meaning |
|---|---|
| 200 | The owner’s own private name for a contact |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
200 response schema
{ "type": "null"}curl -X PATCH 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/petname' \ -H "Authorization: Bearer $BATONDECK_API_KEY" \ -H 'content-type: application/json' \ -d @body.jsonRe-fetch ONE contact’s signed card now, and say what was found (HDTP §14.3)
Section titled “Re-fetch ONE contact’s signed card now, and say what was found (HDTP §14.3)”POST /v1/identities/{slug}/contacts/{fingerprint}/refresh · operation refreshContact
Requires the batondeck:contacts:manage permission (action contact:write).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Request body (application/json)
Request schema
{ "type": "object", "properties": {}, "additionalProperties": false}Responses
| Status | Meaning |
|---|---|
| 200 | Re-fetch ONE contact’s signed card now, and say what was found (HDTP §14.3) |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
| 429 | This identity’s outbound budget (HDTP §12: 1 call a second per contact with a burst of 10, the identity’s aggregate, 20 an hour to strangers), or the peer’s own, refused the call; retry_after and Retry-After say when to try again. |
200 response schema
{ "type": "object", "properties": { "outcome": { "type": "string", "enum": [ "unchanged", "updated", "renewed", "unreachable", "refused" ] }, "why": { "type": "string" } }, "required": [ "outcome" ], "additionalProperties": false}curl -X POST 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/refresh' \ -H "Authorization: Bearer $BATONDECK_API_KEY" \ -H 'content-type: application/json' \ -d @body.jsonWhether this contact may instruct, or only send messages (SPEC §6.2)
Section titled “Whether this contact may instruct, or only send messages (SPEC §6.2)”PATCH /v1/identities/{slug}/contacts/{fingerprint}/trust · operation setTrust
Requires the batondeck:contacts:trust permission (action contact:trust).
Refused while the workspace is suspended or on deletion hold.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
slug |
path | string | yes | |
fingerprint |
path | string | yes |
Request body (application/json)
| Field | Type | Required | Notes |
|---|---|---|---|
trust |
“messages_only” \ | “may_instruct” | yes |
Request schema
{ "type": "object", "properties": { "trust": { "type": "string", "enum": [ "messages_only", "may_instruct" ] } }, "required": [ "trust" ], "additionalProperties": false}Responses
| Status | Meaning |
|---|---|
| 200 | Whether this contact may instruct, or only send messages (SPEC §6.2) |
| 400 | The arguments did not validate. |
| 401 | No portal session, and no live API key. |
| 403 | The policy refused, or the request was cross-site. |
| 404 | No such resource, or none this session may see. |
200 response schema
{ "type": "null"}curl -X PATCH 'https://api.batondeck.com/v1/identities/:slug/contacts/:fingerprint/trust' \ -H "Authorization: Bearer $BATONDECK_API_KEY" \ -H 'content-type: application/json' \ -d @body.json