Enrollment invitations explains what the member sees and what happens to what they add.
Body
| Field | Type | |
|---|---|---|
external_id | string | Required. Up to 200 characters. A member your key's provider holds. |
days | integer | 1 to 90. 30 by default. |
Any other field is refused.
Request
curl -sS "https://3dwarden.com/api/v1/integration/enrollments" \
-H "Authorization: Bearer $WARDEN_KEY" \
-H "Content-Type: application/json" \
-d '{ "external_id": "member-1001", "days": 30 }'const res = await fetch('https://3dwarden.com/api/v1/integration/enrollments', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.WARDEN_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ external_id: member.id, days: 30 }),
})
if (!res.ok) throw new Error(`${res.status} ${(await res.json()).code}`)
const { enroll_url } = await res.json()
// Send enroll_url to the member from your own system. Do not store it: it carries the secret.import os, requests
res = requests.post(
"https://3dwarden.com/api/v1/integration/enrollments",
headers={"Authorization": f"Bearer {os.environ['WARDEN_KEY']}"},
json={"external_id": member_id, "days": 30},
timeout=30,
)
res.raise_for_status()
enroll_url = res.json()["enroll_url"]Response, 201
{
"external_id": "member-1001",
"token": "wen_9c2e41d07b6a4f3e8d1c5b2a90f7e6d4c3b2a1908f7e6d5c4b3a29180f7e6d5c",
"expires_at": "2026-10-21T18:04:11.123456+00:00",
"enroll_url": "https://3dwarden.com/enroll#wen_9c2e41d07b6a4f3e8d1c5b2a90f7e6d4c3b2a1908f7e6d5c4b3a29180f7e6d5c"
}The secret is in this response once. Issuing again for the same member stops the earlier invitation.
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | The body is not JSON, has an unknown field, or days is out of range. |
| 401 | invalid_key | |
| 403 | plan_not_allowed | The organization's plan does not allow invitations. capability is enrollments. |
| 404 | not_found | This key's provider does not hold that member. |
| 429 | rate_limited |