API Reference

    API Documentation

    Complete reference for all CognitoAPI endpoints, parameters, and responses

    Authentication Requirements

    The endpoints take no API key. Calls only send the inputs each endpoint documents, plus an Authorization: Bearer token where a signed-in user is required. Before exposing the API publicly, protect the unauthenticated endpoints at the edge (AWS WAF rate-limiting + API Gateway throttling) to guard against abuse and "financial DDoS" - an API key would not have stopped that anyway, since it is visible in every browser request.

    Postman Collection Setup

    You can find a Postman collection at postman/CognitoApi.postman_collection.json

    You need to set the following variables inside Postman:

    API_BASE_URL

    The DNS name to use to call your auth API.

    EMAIL

    The email of the user you want to create.

    PASSWORD

    The password to use when you create a test user.

    VerificationType

    Must be set to SOFTWARE_TOKEN_MFA.

    Note: The TOTP inside Postman is generated for you automatically using the MFA_SECRET environment variable, which is set from the API call output, once the user has been confirmed.

    Showing all methods
    23 methods
    POST

    /v1/users

    Create a new user in the Cognito User Pool

    Parameters

    NameTypeRequiredDescription
    full_name
    string
    Required
    User's full name
    email
    string
    Required
    User's email
    mobile_phone_number
    string
    Required
    User's mobile phone number

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "status": "CREATED"
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/users"
    payload = {
        "full_name": "Tarek CHEIKH",
        "email": "tarek@tocconsulting.fr",
        "mobile_phone_number": "+3301234567"
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/users/{user_id}/confirm

    Confirm a new user with a temporary password and set a new password

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    temporary_password
    string
    Required
    Temporary password sent to the user's email
    new_password
    string
    Required
    New password for the user

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "qr_code_secret": "UB42J65BKO473DIOOXGWOQZYT7AZKAS7W3AAHVTVT5IPRV",
      "otpauth_uri": "otpauth://totp/CognitoApi:tarek@tocconsulting.fr?secret=UB42J65BKO473DIOOXGWOQZYT7AZKAS7W3AAHVTVT5IPRV&issuer=CognitoApi",
      "mfa_session": "AYABeF...<session>",
      "status": "PENDING_MFA"
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/users/{user_id}/confirm"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "temporary_password": "WpbyHbcIc#pNo3",
        "new_password": "WpbyHbcIc#pNp9"
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/users/{user_id}/confirm-mfa

    Confirm Multi-Factor Authentication for a user

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    otp
    string
    Required
    One-time password from MFA device
    mfa_session
    string
    Required
    The MFA session returned by /confirm; required to complete enrollment

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "mfa_status": "CONFIRMED"
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/users/{user_id}/confirm-mfa"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "otp": "123456",
        "mfa_session": "AYABeF...returned-by-/confirm..."
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/forgot-password

    Initiate a password reset flow for a user

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "status": "PASSWORD_FORGOT_CONFIRMATION_SENT"
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/forgot-password"
    payload = {
        "email": "tarek@tocconsulting.fr"
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/users/{user_id}/confirm-password

    Complete password reset with verification code

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    new_password
    string
    Required
    New password for the user
    verification_code
    string
    Required
    Verification code sent to the user

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "status": "NEW_PASSWORD_SET_SUCCESSFULLY"
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/users/{user_id}/confirm-password"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "new_password": "#Y3KdGR9QKg_a9",
        "verification_code": "304482"
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    GET

    /v1/userinfo

    Get information about the connected user

    Parameters

    NameTypeRequiredDescription
    Authorization
    header
    Required
    Bearer token from login

    Response

    {
      "name": "Tarek CHEIKH",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "email": "tarek@tocconsulting.fr",
      "phone_number": "+3301234567",
      "groups": []
    }

    Example

    import requests
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/userinfo"
    headers = {
        "Authorization": "Bearer eyJraWQiOiJudUFPSENpcStPZnk3enF5TjFBZERSSEpQcUtZS1EwS"
    }
    
    response = requests.get(url, headers=headers)
    result = response.json()
    POST

    /v1/resend-confirmation-code

    Re-send the temporary password / confirmation code to an unconfirmed user.

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "status": "CONFIRMATION_CODE_SENT"
    }

    Example

    import requests, json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/resend-confirmation-code"
    payload = { "email": "tarek@tocconsulting.fr" }
    headers = { "Content-Type": "application/json" }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/users/{user_id}/change-password

    Change the password of a signed-in user (requires the current password and a valid access token).

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    access_token
    string
    Required
    The user's current access token
    old_password
    string
    Required
    The current password
    new_password
    string
    Required
    The new password (must meet the password policy)

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "status": "PASSWORD_SUCCESSFULLY_CHANGED"
    }

    Example

    import requests, json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/users/{user_id}/change-password"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "access_token": "eyJraWQiOi...",
        "old_password": "OldPassw0rd#2026",
        "new_password": "NewPassw0rd#2026"
    }
    headers = { "Content-Type": "application/json" }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/users/{user_id}/reset-password

    Administratively force a password reset. Cognito emails a verification code the user completes via Confirm Forgot Password.

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "status": "PASSWORD_RESET_CONFIRMATION_SENT"
    }

    Example

    import requests, json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/users/{user_id}/reset-password"
    payload = { "email": "tarek@tocconsulting.fr" }
    headers = { "Content-Type": "application/json" }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    DELETE

    /v1/users/{user_id}

    Permanently delete a user. Protected by the Cognito authorizer - requires the user's own ID token as a Bearer token. The target is the path {user_id}, which must match the token's subject; there is no request body.

    Parameters

    NameTypeRequiredDescription
    Authorization
    header
    Required
    Bearer <id_token> (must belong to the {user_id} being deleted)

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "user_id": "129514d4-b081-7004-e470-b6adacd32db4",
      "status": "USER_DELETED"
    }

    Example

    import requests
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/users/{user_id}"
    headers = {
        "Authorization": "Bearer eyJraWQiOi..."   # the user's own ID token
    }
    
    response = requests.delete(url, headers=headers)
    result = response.json()
    POST

    /v1/login

    First step of authentication to obtain verification session

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    password
    string
    Required
    User's password

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "verification_session": "AYABeLHXhcXCnAA3E29UUMbVqKgAHQABAAdTZXJ2aWNlABBDb2duaXRvVXNlclBvb2xz",
      "verification_type": "SOFTWARE_TOKEN_MFA"
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/login"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "password": "WpbyHbcIc#pNp9"
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/mfa-verify

    Second step of authentication to complete MFA challenge

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email address
    verification_type
    string
    Required
    Type of verification (SOFTWARE_TOKEN_MFA)
    verification_session
    string
    Required
    Session from login response
    otp_code
    string
    Required
    One-time password code from MFA device

    Response

    {
      "id_token": "eyJraWQiOiJpK0dwZFZLVUY1eG1ESml6Ukk2YTVWYTV6ZEtyXC8zeElyR",
      "access_token": "eyJraWQiOiJudUFPSENpcStPZnk3enF5TjFBZERSSEpQcUtZS1EwS",
      "refresh_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNB",
      "expires_in": 3600
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/mfa-verify"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "verification_type": "SOFTWARE_TOKEN_MFA",
        "verification_session": "AYABeLHXhcXCnAA3E29UUMbVqKgAHQABAAdTZXJ2aWNlABBDb2duaXRvVXNlclBvb2xz",
        "otp_code": "012345"
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/refresh-token

    Refresh expired tokens using a refresh token

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    refresh_token
    string
    Required
    Valid refresh token from a previous login

    Response

    {
      "email": "tarek@tocconsulting.fr",
      "id_token": "eyJraWQiOiJpK0dwZFZLVUY1eG1ESml6Ukk2YTVWYTV6ZEtyXC8zeElyR2owZk",
      "access_token": "eyJraWQiOiJudUFPSENpcStPZnk3enF5TjFBZERSSEpQcUtZS1EwSU9mUGd",
      "refresh_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVA",
      "expires_in": 3600
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/refresh-token"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "refresh_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ."
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/logout

    Logout a user and invalidate tokens

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    access_token
    string
    Required
    Access token to invalidate

    Response

    {
      "user_status": "logout"
    }

    Example

    import requests
    import json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/logout"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "access_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoi"
    }
    headers = {
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/mfa-reset/start

    Begin authenticator recovery. Emails a one-time recovery code and returns a custom-auth session. Response is generic whether or not the account exists.

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email

    Response

    {
      "status": "MFA_RESET_CODE_SENT",
      "session": "AYABeF...<custom-auth-session>"
    }

    Example

    import requests, json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/mfa-reset/start"
    payload = { "email": "tarek@tocconsulting.fr" }
    headers = { "Content-Type": "application/json" }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/mfa-reset/verify

    Verify the recovery code and password. Returns a fresh TOTP secret to enroll a new authenticator, plus an access token to confirm it.

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    session
    string
    Required
    Session returned by MFA Reset - Start
    code
    string
    Required
    Recovery code from the email
    password
    string
    Required
    The user's current password

    Response

    {
      "qr_code_secret": "MZXW6YTBOI======",
      "otpauth_uri": "otpauth://totp/CognitoApi:tarek@tocconsulting.fr?secret=MZXW6YTBOI======&issuer=CognitoApi",
      "access_token": "eyJraWQiOi...",
      "status": "NEW_TOTP_ISSUED"
    }

    Example

    import requests, json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/mfa-reset/verify"
    payload = {
        "email": "tarek@tocconsulting.fr",
        "session": "AYABeF...",
        "code": "482913",
        "password": "MyPassw0rd#2026"
    }
    headers = { "Content-Type": "application/json" }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/mfa-reset/confirm

    Confirm the new authenticator with a 6-digit code, finishing the reset. The recovery session is then invalidated.

    Parameters

    NameTypeRequiredDescription
    access_token
    string
    Required
    Access token from MFA Reset - Verify
    otp
    string
    Required
    6-digit code from the new authenticator app

    Response

    {
      "status": "MFA_RESET_COMPLETE"
    }

    Example

    import requests, json
    
    url = "https://your-api-id.execute-api.region.amazonaws.com/v1/mfa-reset/confirm"
    payload = { "access_token": "eyJraWQiOi...", "otp": "123456" }
    headers = { "Content-Type": "application/json" }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    result = response.json()
    POST

    /v1/passkeys/register/start

    Begin registering a passkey for a signed-in user. Returns the WebAuthn credential creation options to pass to navigator.credentials.create().

    Parameters

    NameTypeRequiredDescription
    access_token
    string
    Required
    The signed-in user's access token

    Response

    {
      "credential_creation_options": {
        "rp": { "id": "example.com", "name": "example.com" },
        "user": { "id": "...", "name": "tarek@tocconsulting.fr", "displayName": "tarek@tocconsulting.fr" },
        "challenge": "2Xs7JfjluJM16HAbVDZWrw",
        "pubKeyCredParams": [{ "type": "public-key", "alg": -7 }, { "type": "public-key", "alg": -257 }],
        "authenticatorSelection": { "residentKey": "required", "userVerification": "required" }
      }
    }

    Example

    const start = await api("/v1/passkeys/register/start", { access_token });
    const credential = await navigator.credentials.create({
      publicKey: toBuffers(start.credential_creation_options),
    });
    POST

    /v1/passkeys/register/complete

    Finish passkey registration by sending the credential produced by the browser.

    Parameters

    NameTypeRequiredDescription
    access_token
    string
    Required
    The signed-in user's access token
    credential
    object
    Required
    The PublicKeyCredential.toJSON() from navigator.credentials.create()

    Response

    {
      "status": "PASSKEY_REGISTERED"
    }

    Example

    await api("/v1/passkeys/register/complete", { access_token, credential: cred.toJSON() });
    POST

    /v1/passkeys/list

    List the WebAuthn credentials registered for a signed-in user.

    Parameters

    NameTypeRequiredDescription
    access_token
    string
    Required
    The signed-in user's access token

    Response

    {
      "credentials": [
        {
          "CredentialId": "x9s...",
          "FriendlyCredentialName": "iCloud Keychain",
          "RelyingPartyId": "example.com",
          "AuthenticatorAttachment": "platform",
          "CreatedAt": "2026-06-14T11:40:27Z"
        }
      ]
    }

    Example

    const { credentials } = await api("/v1/passkeys/list", { access_token });
    POST

    /v1/passkeys/delete

    Remove a registered passkey by its credential id.

    Parameters

    NameTypeRequiredDescription
    access_token
    string
    Required
    The signed-in user's access token
    credential_id
    string
    Required
    Id of the credential to delete (from Passkey List)

    Response

    {
      "status": "PASSKEY_DELETED"
    }

    Example

    await api("/v1/passkeys/delete", { access_token, credential_id: "x9s..." });
    POST

    /v1/passkeys/login/start

    Begin passwordless sign-in. Returns a session and the WebAuthn request options for navigator.credentials.get(). Response is generic whether or not the account/passkey exists.

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email

    Response

    {
      "session": "AYABeF...",
      "credential_request_options": "{\"challenge\":\"...\",\"rpId\":\"example.com\",\"allowCredentials\":[...]}"
    }

    Example

    const start = await api("/v1/passkeys/login/start", { email });
    const assertion = await navigator.credentials.get({
      publicKey: toBuffers(JSON.parse(start.credential_request_options)),
    });
    POST

    /v1/passkeys/login/complete

    Finish passwordless sign-in by answering the WebAuthn challenge. Returns tokens on success - no password or TOTP needed.

    Parameters

    NameTypeRequiredDescription
    email
    string
    Required
    User's email
    session
    string
    Required
    Session from Passkey Login - Start
    credential
    object
    Required
    The assertion from navigator.credentials.get()

    Response

    {
      "id_token": "eyJraWQiOi...",
      "access_token": "eyJraWQiOi...",
      "refresh_token": "eyJjdHkiOi...",
      "expires_in": 3600,
      "token_type": "Bearer"
    }

    Example

    const tokens = await api("/v1/passkeys/login/complete", {
      email, session: start.session, credential: assertion.toJSON(),
    });

    API Usage Notes

    Authentication

    The API takes no API key. Only GET /v1/userinfo and DELETE /v1/users/{id} require a Bearer JWT (enforced by a Cognito User Pools authorizer); the remaining endpoints are open. For protected calls, include the token in the Authorization header:

    Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

    Access tokens expire after a configurable period (typically 1 hour). Use the refresh token endpoint to obtain new tokens without requiring the user to log in again.

    Error Handling

    The API uses standard HTTP status codes along with detailed error information in the response body:

    {
      "message": "Invalid credentials"
    }
    
    {
      "message": "Password does not meet complexity requirements"
    }
    
    {
      "message": "Token has expired"
    }

    Common Error Codes

    • 400 Bad Request - The request could not be understood or was missing required parameters
    • 401 Unauthorized - Authentication failed or user doesn't have permissions
    • 403 Forbidden - Authenticated user doesn't have access to the requested resource
    • 404 Not Found - Resource not found
    • 429 Too Many Requests - Request throttled due to too many requests
    • 500 Internal Server Error - An error occurred on the server

    JWT Tokens

    The API provides three types of tokens:

    Token Types

    • Access Token - Used to access protected resources, short-lived (typically 1 hour)
    • ID Token - Contains user profile information, including email and other attributes
    • Refresh Token - Used to obtain new access tokens when they expire, longer-lived (24 hours)

    All tokens are JWT format, and you can decode them to inspect their contents using tools like jwt.io.

    Deployment

    The API is deployed using Terraform, making it easy to provision and manage your Cognito API infrastructure. The infrastructure is designed to be cost-efficient and secure.

    AWS Resources

    • API Gateway - REST API with CORS enabled
    • Lambda Functions - Python-based handlers for authentication operations
    • Cognito User Pool - User identity management
    • CloudWatch Logs - Monitoring and troubleshooting
    • IAM Roles and Policies - Secure access management

    For details on deploying the API, refer to the Getting Started section and the project's README file on GitHub.