err:user:bad_request:permissions_query_syntax_error
{
"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:
- A single permission:
permission_1
- Multiple permissions with AND:
permission_1 AND permission_2
- Multiple permissions with OR:
permission_1 OR permission_2
- 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"
}'
Simple Names
permission_1
user_read
admin-access
Namespaced Permissions
api.users.read
billing.invoices.create
workspace.settings.update
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.