Skip to main content
This guide covers the changes to identity endpoints between v1 and v2. Both versions provide full identity management capabilities with different API patterns.

Overview

What Changed in v2:

  • HTTP methods: GET endpoints changed to POST for consistency
  • Request format: Query parameters moved to request body
  • Response format: Direct response wrapped in structured {meta, data} format
  • Parameter flexibility: Enhanced parameter handling (accepts both identityId and externalId)
  • Error handling: Improved error response structure

Migration Impact:

  • v1: Mixed GET/POST with query parameters and direct responses
  • v2: All POST with request bodies and structured {meta, data} responses
  • Benefit: Consistent API patterns, better error tracking, enhanced flexibility

POST /v1/identities.createIdentity → POST /v2/identities.createIdentity

Purpose: Create a new identity with metadata and rate limits. Changes: Request format unchanged, response wrapped in structured format.
v1 vs v2: Create Identity Request
// v1: POST /v1/identities.createIdentity
{
  "externalId": "user_123",
  "meta": {
    "email": "[email protected]",
    "plan": "pro"
  },
  "ratelimits": [
    {
      "name": "requests",
      "limit": 1000,
      "duration": 3600000
    }
  ]
}

// v2: POST /v2/identities.createIdentity (same request format)
{
  "externalId": "user_123",
  "meta": {
    "email": "[email protected]",
    "plan": "pro"
  },
  "ratelimits": [
    {
      "name": "requests",
      "limit": 1000,
      "duration": 3600000
    }
  ]
}

GET /v1/identities.getIdentity → POST /v2/identities.getIdentity

Purpose: Retrieve identity data by ID or external ID. Key Changes: GET with query parameters → POST with request body, response format enhanced.
v1 vs v2: Get Identity Request
# v1: GET with query parameters
curl -X GET "https://api.unkey.dev/v1/identities.getIdentity?externalId=user_123" \
  -H "Authorization: Bearer <your-root-key>"

# Alternative v1: Using identityId
curl -X GET "https://api.unkey.dev/v1/identities.getIdentity?identityId=identity_123" \
  -H "Authorization: Bearer <your-root-key>"

# v2: POST with request body (accepts both ID types)
curl -X POST https://api.unkey.com/v2/identities.getIdentity \
  -H "Authorization: Bearer <your-root-key>" \
  -H "Content-Type: application/json" \
  -d '{"identity": "user_123"}'

GET /v1/identities.listIdentities → POST /v2/identities.listIdentities

Purpose: Get paginated list of all identities. Key Changes: GET with query parameters → POST with request body, enhanced pagination structure.
v1 vs v2: List Identities Request
# v1: GET with query parameters
curl -X GET "https://api.unkey.dev/v1/identities.listIdentities?limit=50&cursor=eyJrZXkiOiJrZXlfMTIzNCJ9" \
  -H "Authorization: Bearer <your-root-key>"

# v2: POST with request body
curl -X POST https://api.unkey.com/v2/identities.listIdentities \
  -H "Authorization: Bearer <your-root-key>" \
  -H "Content-Type: application/json" \
  -d '{"limit": 50, "cursor": "eyJrZXkiOiJrZXlfMTIzNCJ9"}'

POST /v1/identities.updateIdentity → POST /v2/identities.updateIdentity

Purpose: Update identity metadata and rate limits. Changes: Enhanced parameter flexibility, structured response format.
v1 vs v2: Update Identity Request
// v1: Requires specific ID field
{
  "identityId": "id_abc123",  // or "externalId": "user_123"
  "meta": {
    "email": "[email protected]",
    "plan": "enterprise"
  },
  "ratelimits": [
    {
      "name": "requests",
      "limit": 5000,
      "duration": 3600000
    }
  ]
}

// v2: Flexible identity parameter
{
  "identity": "user_123",  // accepts both identityId or externalId
  "meta": {
    "email": "[email protected]",
    "plan": "enterprise"
  },
  "ratelimits": [
    {
      "name": "requests",
      "limit": 5000,
      "duration": 3600000
    }
  ]
}

POST /v1/identities.deleteIdentity → POST /v2/identities.deleteIdentity

Purpose: Permanently delete an identity. Changes: Enhanced parameter flexibility (v2 accepts both ID types), structured response.
v1 vs v2: Delete Identity Request
// v1: Requires identityId specifically
{
  "identityId": "id_abc123def456"
}

// v2: Flexible identity parameter
{
  "identity": "user_123"  // accepts both identityId or externalId
}