Identity API

The Identity resource is your starting point for working with the Droplet API. It answers the question "who am I, and what am I allowed to do?" by exchanging your bearer token for a client access token, along with the organization context and permission map that come with it. If you are bootstrapping a session or building a client that needs to know its own identity before doing anything else, this is the call you make first.

Identity API

Issue a client access token

POST /v1/identity/client-access

Call this endpoint to exchange your API token (your identityToken) for a short-lived client access token, valid for 5 minutes. The response also hands back the organization you are operating in, its plan limits, and a granular permission map so your client knows exactly what it can see and do. There is no request body to send. Just authenticate with your bearer token and Droplet figures out the rest from the token itself.

The access token is valid for 5 minutes. Reuse it across calls until it expires, then call this endpoint again for a fresh one. A 401 on an otherwise-correct request almost always means the access token has expired, that is your cue to refresh.

Think of this as a whoami call with benefits. One request tells you your organization, your plan limits, and your permissions, so you can tailor the rest of your session without guessing.

Authentication

This endpoint is authenticated with your API token in the Authorization header:

Authorization: Bearer <token>

Request

This endpoint takes no path parameters and no request body. The identity it returns is derived entirely from the bearer token you present.

Example request

curl -X POST https://api.droplet.io/v1/identity/client-access \
  -H "Authorization: Bearer <token>"

Response

A successful call returns the standard envelope with success: true and a data object containing the organization, your access token, and your permission map.

FieldTypeDescription
data.organizationobjectThe organization tied to your token. Always includes an id.
data.organization.idstringUnique identifier for the organization.
data.organization.namestringDisplay name of the organization.
data.organization.limitsobjectPlan limits, or null if unlimited. Includes publishedForms and viewSubmissions.
data.organization.freebooleanWhether the organization is on a free plan.
data.organization.directorySyncEnabledbooleanWhether directory sync is enabled for the organization.
data.accessTokenstringThe client access token to use for subsequent requests.
data.permissionsobjectA nested map of resource to action to boolean, describing what you can do.

Example response

{
  "requestId": "req_8f3a1c92",
  "success": true,
  "data": {
    "organization": {
      "id": "org_4b21d7",
      "name": "Acme Inc",
      "limits": {
        "publishedForms": 50,
        "viewSubmissions": 10000
      },
      "free": false,
      "directorySyncEnabled": true
    },
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "permissions": {
      "forms": {
        "create": true,
        "publish": true,
        "delete": false
      },
      "submissions": {
        "view": true,
        "export": false
      }
    }
  }
}

Errors

When something goes wrong, you get the same envelope with success: false and an error object carrying a code and a human-readable message.

{
  "requestId": "req_8f3a1c92",
  "success": false,
  "error": {
    "code": "unauthorized",
    "message": "The provided token is invalid or has expired."
  }
}

What you can do with it

Once you have the response in hand, you can:

  • Use data.accessToken to authenticate the rest of your client session.
  • Read data.organization.limits to show usage caps or gate features in your UI.
  • Check data.permissions before attempting an action, so you only surface what the user can actually do.
  • Branch on data.organization.free or directorySyncEnabled to tailor the experience to the plan.
Last reviewed by Nick Duell and published on June 22, 2026 9PM ET