Example
{
  "meta": {
    "requestId": "req_2c9a0jf23l4k567"
  },
  "error": {
    "detail": "Syntax error in permission query: unexpected token 'AND' at position 15. Expected permission name or opening parenthesis.",
    "status": 400,
    "title": "Bad Request",
    "type": "https://unkey.com/docs/api-reference/errors-v2/user/bad_request/permissions_query_syntax_error",
    "errors": [
      {
        "location": "body.permissions",
        "message": "unexpected token 'AND' at position 15",
        "fix": "Check your query syntax. AND/OR operators must be between permissions, not at the start or end"
      }
    ]
  }
}

What Happened?

This error occurs when the permissions query in your verifyKey request contains invalid syntax or characters. This can happen due to:
  • Invalid characters in permission names (lexical errors)
  • Incorrect query structure like missing operands or unmatched parentheses (syntax errors)
  • Malformed expressions that don’t follow the expected grammar

Permissions Query Requirements

The verifyKey endpoint accepts a permissions query string that must follow these rules:

Valid Characters

The query parser accepts these characters:
  • Permissions: Must follow the permission slug format (alphanumeric, dots, underscores, hyphens)
    • Letters: a-z, A-Z
    • Numbers: 0-9
    • Dots: . for permission namespacing
    • Underscores: _ in identifiers
    • Hyphens: - in identifiers
  • Query operators: AND, OR (case insensitive)
  • Grouping: ( ) for parentheses
  • Whitespace: Spaces, tabs and new lines for separation (ignored by parser)
Everything else is not allowed.

Query Structure

A permissions query can be:
  1. A single permission: permission_1
  2. Multiple permissions with AND: permission_1 AND permission_2
  3. Multiple permissions with OR: permission_1 OR permission_2
  4. Grouped expressions: (permission_1 OR permission_2) AND permission_3
Key rules:
  • Permission names must be valid permission slugs (letters, numbers, dots, underscores, hyphens)
  • Use AND when all permissions are required
  • Use OR when any of the permissions is sufficient
  • Use parentheses () to group expressions and control precedence
  • Operators are case insensitive: AND, AnD, and all work.

Common Errors and Solutions

1. Invalid Characters

# ❌ Invalid - contains special characters
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission$1 OR permission@2"
  }'

# ✅ Valid - use underscores or hyphens
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 OR permission_2"
  }'

2. Missing Operands

# ❌ Invalid - AND without right operand
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 AND"
  }'

# ✅ Valid - complete AND expression
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 AND permission_2"
  }'

3. Unmatched Parentheses

# ❌ Invalid - missing closing parenthesis
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "(permission_1 AND permission_2"
  }'

# ✅ Valid - balanced parentheses
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "(permission_1 AND permission_2)"
  }'

4. Empty Parentheses

# ❌ Invalid - empty parentheses
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 AND ()"
  }'

# ✅ Valid - parentheses with content
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 AND (permission_2 OR permission_3)"
  }'

5. Incorrect Operator Placement

# ❌ Invalid - operator at start
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "OR permission_1"
  }'

# ✅ Valid - operators between permissions
curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 OR permission_2"
  }'

Valid Query Examples

Simple Permission

curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1"
  }'

AND Operation

curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 AND permission_2"
  }'

OR Operation

curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "permission_1 OR permission_2"
  }'

Complex Expressions

curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "(permission_1 OR permission_2) AND permission_3"
  }'

Nested Expressions

curl -X POST https://api.unkey.com/v2/keys.verifyKey \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer unkey_XXXX" \
  -d '{
    "key": "sk_123",
    "permissions": "((permission_1 OR permission_2) AND permission_3) OR permission_4"
  }'

Valid Permission Formats

Simple Names

  • permission_1
  • user_read
  • admin-access

Namespaced Permissions

  • api.users.read
  • billing.invoices.create
  • workspace.settings.update

Mixed Formats

  • user_management.create
  • billing-service.view
  • service123.feature_a.read

Context

This error is specific to the verifyKey endpoint’s permissions query parsing. The query is validated at the application level to ensure it conforms to the expected permission query language syntax. Basic validation like empty strings and length limits are handled at the OpenAPI level before reaching this parser.