TOTP (Authenticator)
Store TOTP secrets and generate 2FA codes via API — no phone-based authenticator app required for your agents
The TOTP API lets you store encrypted TOTP secrets and generate 2FA codes programmatically. Instead of requiring an AI agent or automation to use a phone-based authenticator app, you can store the secret once and call the API whenever a 6-digit code is needed.
Secrets are encrypted at rest with AES-256-GCM. The plaintext secret is returned once at registration and never again.
Register a TOTP Secret
Section titled “Register a TOTP Secret”Store a new TOTP secret. You can provide either a raw secret (base32) or a full otpauth:// URI from a QR code scan.
POST https://api.sendblue.com/api/v2/totp/secretsRequest Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
label | string | Yes* | Human-readable label (e.g. "GitHub - [email protected]"). Required unless uri is provided. |
uri | string | No | Full otpauth://totp/... URI from a QR code. Overrides all other fields. |
secret | string | No | Base32-encoded TOTP secret. Omit to auto-generate. |
issuer | string | No | Service name (e.g. "GitHub", "Google") |
algorithm | string | No | SHA1 (default), SHA256, or SHA512 |
digits | integer | No | Code length: 6 (default) or 8 |
period | integer | No | Rotation period in seconds (default: 30) |
Example — from a QR code URI
Section titled “Example — from a QR code URI”curl -X POST 'https://api.sendblue.com/api/v2/totp/secrets' \ -H 'sb-api-key-id: YOUR_API_KEY' \ -H 'sb-api-secret-key: YOUR_API_SECRET' \ -H 'Content-Type: application/json' \ -d '{ "uri": "otpauth://totp/GitHub:agent%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub" }'Example — from a raw secret
Section titled “Example — from a raw secret”curl -X POST 'https://api.sendblue.com/api/v2/totp/secrets' \ -H 'sb-api-key-id: YOUR_API_KEY' \ -H 'sb-api-secret-key: YOUR_API_SECRET' \ -H 'Content-Type: application/json' \ -d '{ "label": "GitHub - [email protected]", "secret": "JBSWY3DPEHPK3PXP", "issuer": "GitHub" }'Success Response (200)
Section titled “Success Response (200)”The plaintext secret is returned only on creation. Save it if you need it — it is never returned again.
{ "status": "OK", "totp_secret": { "id": "550e8400-e29b-41d4-a716-446655440000", "issuer": "GitHub", "algorithm": "SHA1", "digits": 6, "period": 30, "secret": "JBSWY3DPEHPK3PXP", "created_at": "2026-04-05T12:00:00Z" }}Get Current TOTP Code
Section titled “Get Current TOTP Code”Generate the current code for a stored secret. Also returns expires_in — seconds until the code rotates — so your agent knows when to retry if a code is rejected.
GET https://api.sendblue.com/api/v2/totp/code/:secret_idPath Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
secret_id | string (UUID) | ID of the stored TOTP secret |
Example Request
Section titled “Example Request”curl 'https://api.sendblue.com/api/v2/totp/code/550e8400-e29b-41d4-a716-446655440000' \ -H 'sb-api-key-id: YOUR_API_KEY' \ -H 'sb-api-secret-key: YOUR_API_SECRET'Success Response (200)
Section titled “Success Response (200)”{ "status": "OK", "code": "482031", "expires_in": 14}expires_in is the number of seconds remaining in the current time window. If a 2FA form rejects the code, wait until expires_in reaches 0 and fetch a new one.
List TOTP Secrets
Section titled “List TOTP Secrets”List all stored secrets for your account. Secret values are never included.
GET https://api.sendblue.com/api/v2/totp/secretsExample Request
Section titled “Example Request”curl 'https://api.sendblue.com/api/v2/totp/secrets' \ -H 'sb-api-key-id: YOUR_API_KEY' \ -H 'sb-api-secret-key: YOUR_API_SECRET'Success Response (200)
Section titled “Success Response (200)”{ "status": "OK", "totp_secrets": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "issuer": "GitHub", "algorithm": "SHA1", "digits": 6, "period": 30, "created_at": "2026-04-05T12:00:00Z" } ]}Delete a TOTP Secret
Section titled “Delete a TOTP Secret”Permanently delete a stored secret.
DELETE https://api.sendblue.com/api/v2/totp/secrets/:secret_idPath Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
secret_id | string (UUID) | ID of the TOTP secret to delete |
Example Request
Section titled “Example Request”curl -X DELETE 'https://api.sendblue.com/api/v2/totp/secrets/550e8400-e29b-41d4-a716-446655440000' \ -H 'sb-api-key-id: YOUR_API_KEY' \ -H 'sb-api-secret-key: YOUR_API_SECRET'Success Response (200)
Section titled “Success Response (200)”{ "status": "OK"}Error Responses
Section titled “Error Responses”Bad Request (400)
Section titled “Bad Request (400)”{ "status": "ERROR", "message": "label is required (or provide a uri)"}Unauthorized (401)
Section titled “Unauthorized (401)”{ "status": "ERROR", "message": "Unauthorized"}Not Found (404)
Section titled “Not Found (404)”{ "status": "ERROR", "message": "TOTP secret not found"}Conflict (409)
Section titled “Conflict (409)”{ "status": "ERROR", "message": "A secret with this label already exists"}- Security: Secrets are encrypted at rest with AES-256-GCM. The plaintext secret is only returned at registration time.
- URI format: Most services display a QR code during 2FA setup. If your setup flow shows a “can’t scan?” fallback, that link is the
otpauth://URI — pass it directly asuri. - Timing: TOTP codes are time-based. If a code is rejected, check
expires_inand wait for the next window before retrying. - Label uniqueness: Labels must be unique within your account. Use descriptive labels like
"service - [email protected]"to avoid conflicts.