Ask for an invitation
Menu

Endpoint

Invite a member

POST/v1/team/invitations

No API key changes the team: after checking email and role, this call answers passkey_approval_required for every role. A signed-in member invites people in the dashboard, with a passkey; the invitation is valid for 7 days.

Scope a restricted key needs
team:write
Publishable key
Not allowed: secret or restricted key only
Idempotency-Key
Recommended. It makes a retry safe.

Parameters

Parameters of Invite a member
ParameterType and placeMeaning
Orrerie-VersionstringheaderAPI version date. Default: the version the key was created with. Example 2026-10-11.
Idempotency-KeystringheaderMakes a retry safe. Kept 24 hours. 1 to 255 characters.

Request body

A JSON object. The body is required. A field the call does not list is refused with parameter_unknown.

Request body of Invite a member
FieldTypeMeaning
emailrequiredstringThe address the invitation is sent to.
rolerequiredstringOne of admin, developer, support, cashier, viewer.
namestringThe person's name, shown in the invitation.

Example request

Refused in this release

Every request to this call is answered 403 with passkey_approval_required and reason members_dashboard_only. A signed-in member invites people in the dashboard, with a passkey.

curl

curl https://api.orrerie.com/v1/team/invitations \
  -H "Authorization: Bearer $ORRERIE_SECRET_KEY" \
  -H "Idempotency-Key: 8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "dev@acme.example",
  "role": "developer",
  "name": "Lee Park"
}'

JavaScript

const response = await fetch("https://api.orrerie.com/v1/team/invitations", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ORRERIE_SECRET_KEY}`,
    "Idempotency-Key": "8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "email": "dev@acme.example",
    "role": "developer",
    "name": "Lee Park"
  }),
});
const result = await response.json();
if (!response.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
console.log(result);

Python

import os
import requests

response = requests.post(
    "https://api.orrerie.com/v1/team/invitations",
    headers={"Authorization": f"Bearer {os.environ['ORRERIE_SECRET_KEY']}", "Idempotency-Key": "8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a"},
    json={
        "email": "dev@acme.example",
        "role": "developer",
        "name": "Lee Park",
    },
    timeout=30,
)
result = response.json()
if not response.ok:
    raise RuntimeError(f"{result['error']['code']}: {result['error']['message']}")
print(result)

PHP

<?php
$request = curl_init('https://api.orrerie.com/v1/team/invitations');
curl_setopt_array($request, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('ORRERIE_SECRET_KEY'),
        'Idempotency-Key: 8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'email' => 'dev@acme.example',
        'role' => 'developer',
        'name' => 'Lee Park',
    ]),
]);
$body = curl_exec($request);
if ($body === false) {
    throw new RuntimeException(curl_error($request));
}
$result = json_decode($body, true);
if (curl_getinfo($request, CURLINFO_HTTP_CODE) >= 400) {
    throw new RuntimeException($result['error']['code'] . ': ' . $result['error']['message']);
}
print_r($result);

Responses

201 Created

The answer is the member object. Headers: Orrerie-Request-Id.

Example response, 201

{
  "id": "mem_ddc4wbzck462zs616tww8gw8",
  "object": "member",
  "livemode": true,
  "created": "2026-10-12T12:00:00.000Z",
  "user": null,
  "email": "dev@acme.example",
  "name": "Lee Park",
  "role": "developer",
  "status": "invited",
  "holds_wallet_key": false,
  "passkey_count": 0,
  "invited_by": null,
  "invitation_expires_at": "2026-10-19T12:00:00.000Z",
  "last_active_at": null
}

Any other status: an error

A status of 400 or above answers with the error object. Branch on its code, never on its message.

Errors

Beside the errors every call can answer with (a bad key, a missing scope, the rate limit), this call answers with:

Errors of Invite a member
CodeHTTPMeaning
passkey_approval_required403The action can only be done by a signed-in member in the dashboard (settlement asset, key-holding roles, approvals). No API key can do it.