Cowdidocs
API ReferenceContact details

Add an email

POST
/v1/user/settings/emails

Adds a global pending email to the caller's profile after recent authentication, and sends an OTP to it. Pending contacts do not reserve the identity; the first caller to verify a value wins the global claim. Five invalid OTP confirmations lock the contact until a platform admin resets it. Returns 400 when the caller already has the maximum number of email contacts. The returned otp tells where the OTP went. Confirm the OTP next. The first email of a caller with no primary email becomes the primary email when its verification completes. With an open current account, the account provider sends its OTPs. While the current account is pending, Cowdi sends the OTP.

AuthorizationBearer <token>

Create a client with POST /v1/oauth/clients, then exchange its credentials for an access token. AUTHORIZATION_CODE clients act on behalf of a signed-in user and always use PKCE; CLIENT_CREDENTIALS clients act as themselves. A client may only be granted scopes its creator already holds — read the grantable list from GET /v1/oauth/clients/scopes.

In: header

Request Body

application/json

The email address to add as a pending contact on the caller's profile.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/user/settings/emails" \  -H "Content-Type: application/json" \  -d '{    "email": "jane@example.com"  }'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "value": "jane@example.com",  "otp": {    "step": "OWNER_AUTHORIZATION",    "sent_to": "EMAIL",    "steps": 2,    "digits": 6  },  "is_primary": true,  "validated": true,  "validated_at": "2026-01-15T09:20:00Z",  "requires_verification": true,  "verification_locked": true,  "verification_locked_at": "2026-01-20T16:45:00Z",  "created_at": "2026-09-01T10:15:30Z"}
{  "code": "BAD_REQUEST",  "description": "Bad Request"}
{  "code": "UNAUTHORISED",  "description": "Unauthorised"}
{  "code": "FORBIDDEN",  "description": "Forbidden"}
{  "code": "RATE_LIMIT_EXCEEDED",  "description": "Too Many Requests"}
{  "code": "INTERNAL_ERROR",  "description": "Internal Server Error"}