On this page
- Key format
- Restricted permissions
- Access levels
- Resource groups
- Endpoints
- List API keys
- Query parameters
- Request
- Response 200
- Create an API key
- Request body
- Request
- Response 201
- Roll (rotate) an API key
- Request body
- Request
- Response 201
- Update key permissions
- Request body
- Request
- Response 200
- Revoke an API key
- Request
- Response 200
- The API key object
API Keys
Manage API keys for programmatic access to your project. Keys come in two types (secret and publishable) and two modes (live and test).
Base URL: https://api.hydrajs.dev
ℹAdmin authentication required
All API key endpoints require admin (JWT) authentication. API keys cannot manage other API keys — this prevents privilege escalation if a key is compromised.
Key format
| Prefix | Type | Mode | Usage |
|---|---|---|---|
sk_live_ |
Secret | Live | Full CRUD, server-side only |
sk_test_ |
Secret | Test | Full CRUD, server-side only |
pk_live_ |
Publishable | Live | Read-only + cart/checkout, client-safe |
pk_test_ |
Publishable | Test | Read-only + cart/checkout, client-safe |
Keys are 40 characters total (8-character prefix + 32 random alphanumeric characters). Plaintext is shown once at creation — only the last 8 characters are stored for display.
Restricted permissions
Keys can optionally be scoped to specific resource groups with granular access levels. A key with permissions: null has full access (the default). A key with a permissions object is restricted to the specified access levels.
Access levels
| Level | Allowed methods | Description |
|---|---|---|
none |
— | No access to the resource |
read |
GET |
Read-only access |
write |
GET, POST, PUT, PATCH, DELETE |
Full access (write implies read) |
Resource groups
| Resource | Routes covered |
|---|---|
catalog |
Products, variants, collections, images, tags, search, Google taxonomy, HS codes |
orders |
Orders, checkout |
customers |
Customers, addresses |
inventory |
Inventory |
shipping |
Shipping zones and rates |
promotions |
Promotions |
tax |
Tax configuration |
developer |
Webhooks, redirects, events |
settings |
Store settings, exchange rates, payments, price keys |
cart |
Cart |
ℹPermissions can only narrow access
Restricted permissions work alongside key type permissions. A publishable key with orders: write
still cannot create orders — publishable keys are read-only for orders by design. Restricted
permissions can only narrow access, never widen it.
Endpoints
| Method | Path | Description |
|---|---|---|
GET |
/v1/store/keys |
List all keys |
POST |
/v1/store/keys |
Create a new key |
POST |
/v1/store/keys/{id}/roll |
Roll (rotate) a key |
PATCH |
/v1/store/keys/{id}/permissions |
Update key permissions |
POST |
/v1/store/keys/{id}/revoke |
Revoke a key |
List API keys
GET /v1/store/keys
Returns all keys for the project, including revoked keys. Never returns plaintext or hashes.
Query parameters
| Parameter | Type | Description |
|---|---|---|
is_test |
boolean | Filter by mode. Omit to return all keys. |
Request
curl https://api.hydrajs.dev/v1/store/keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-Store-Id: store_abc123"
Response 200
{
"data": [
{
"id": "key_abc123",
"name": null,
"key_prefix": "sk_live_",
"key_hint": "abc12345",
"type": "secret",
"is_test": false,
"is_active": true,
"permissions": null,
"expires_at": null,
"last_used_at": "2026-08-20T14:30:00.000Z",
"created_at": "2026-08-12T08:00:00.000Z",
"updated_at": "2026-08-12T08:00:00.000Z"
},
{
"id": "key_def456",
"name": "Storefront",
"key_prefix": "pk_live_",
"key_hint": "xyz98765",
"type": "publishable",
"is_test": false,
"is_active": true,
"permissions": {
"catalog": "read",
"orders": "none",
"customers": "none",
"inventory": "none",
"shipping": "none",
"promotions": "none",
"tax": "none",
"developer": "none",
"settings": "none",
"cart": "write"
},
"expires_at": null,
"last_used_at": null,
"created_at": "2026-08-12T08:00:00.000Z",
"updated_at": "2026-08-12T08:00:00.000Z"
}
]
}
Create an API key
POST /v1/store/keys
Creates a new key. The mode (test/live) is inherited from the X-Test-Mode header. The plaintext key is returned once and cannot be retrieved again.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | "secret" or "publishable" |
name |
string | No | Optional label (max 100 chars) |
permissions |
object | null | No | Restricted permissions (see resource groups). Omit or pass null for full access. |
Request
curl -X POST https://api.hydrajs.dev/v1/store/keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-Store-Id: store_abc123" \
-H "Content-Type: application/json" \
-d '{"type": "secret", "name": "CI Pipeline"}'
Creating a restricted key
curl -X POST https://api.hydrajs.dev/v1/store/keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-Store-Id: store_abc123" \
-H "Content-Type: application/json" \
-d '{
"type": "secret",
"name": "Fulfillment Service",
"permissions": {
"catalog": "read",
"orders": "read",
"customers": "none",
"inventory": "write",
"shipping": "read",
"promotions": "none",
"tax": "none",
"developer": "none",
"settings": "none",
"cart": "none"
}
}'
Response 201
{
"data": {
"id": "key_ghi789",
"name": "CI Pipeline",
"key": "sk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
"key_prefix": "sk_live_",
"key_hint": "Z012345",
"type": "secret",
"is_test": false,
"is_active": true,
"permissions": null,
"expires_at": null,
"last_used_at": null,
"created_at": "2026-08-22T10:00:00.000Z",
"updated_at": "2026-08-22T10:00:00.000Z"
}
}
⚠Store this key securely
The key field is only included in the create and roll responses. It is never returned again.
Store it immediately in a secure location.
Roll (rotate) an API key
POST /v1/store/keys/{id}/roll
Generates a new key with the same type and mode. Supports an optional grace period — the old key remains active until the grace period expires, preventing outages during deployment.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
grace_period_hours |
integer | No | Hours to keep the old key active (0–168). Default: 0 (immediate deactivation). |
permissions |
object | null | No | Permissions for the new key. Omit to inherit the old key’s permissions. |
Request
curl -X POST https://api.hydrajs.dev/v1/store/keys/key_abc123/roll \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-Store-Id: store_abc123" \
-H "Content-Type: application/json" \
-d '{"grace_period_hours": 24}'
Response 201
Same shape as the create response — includes the key field with the new plaintext.
When a grace period is set, the old key’s expires_at field is updated to the expiry time. The old key continues to work until that time, then fails auth with a specific error message.
Update key permissions
PATCH /v1/store/keys/{id}/permissions
Updates the permissions on an active key without re-issuing it. Pass null to remove restrictions and grant full access.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
permissions |
object | null | Yes | New permissions, or null for full access. |
Request
curl -X PATCH https://api.hydrajs.dev/v1/store/keys/key_abc123/permissions \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-Store-Id: store_abc123" \
-H "Content-Type: application/json" \
-d '{
"permissions": {
"catalog": "write",
"orders": "read",
"customers": "none",
"inventory": "write",
"shipping": "none",
"promotions": "none",
"tax": "none",
"developer": "none",
"settings": "none",
"cart": "none"
}
}'
Response 200
{
"data": {
"id": "key_abc123",
"name": "Fulfillment Service",
"key_prefix": "sk_live_",
"key_hint": "abc12345",
"type": "secret",
"is_test": false,
"is_active": true,
"permissions": {
"catalog": "write",
"orders": "read",
"customers": "none",
"inventory": "write",
"shipping": "none",
"promotions": "none",
"tax": "none",
"developer": "none",
"settings": "none",
"cart": "none"
},
"expires_at": null,
"last_used_at": "2026-08-20T14:30:00.000Z",
"created_at": "2026-08-12T08:00:00.000Z",
"updated_at": "2026-08-22T12:00:00.000Z"
}
}
Revoke an API key
POST /v1/store/keys/{id}/revoke
Permanently deactivates a key. The key row is preserved for audit trail. This action cannot be undone.
Request
curl -X POST https://api.hydrajs.dev/v1/store/keys/key_abc123/revoke \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-Store-Id: store_abc123"
Response 200
{
"data": {
"id": "key_abc123",
"name": null,
"key_prefix": "sk_live_",
"key_hint": "abc12345",
"type": "secret",
"is_test": false,
"is_active": false,
"permissions": null,
"expires_at": null,
"last_used_at": "2026-08-20T14:30:00.000Z",
"created_at": "2026-08-12T08:00:00.000Z",
"updated_at": "2026-08-22T11:00:00.000Z"
}
}
The API key object
| Field | Type | Description |
|---|---|---|
id |
string | Unique key identifier (e.g. key_abc123) |
name |
string | null | Optional label for identifying the key |
key |
string | Full plaintext key (only in create/roll responses) |
key_prefix |
string | Key prefix (e.g. sk_live_) |
key_hint |
string | Last 8 characters of the key body |
type |
string | "secret" or "publishable" |
is_test |
boolean | Whether the key operates in test mode |
is_active |
boolean | false after revocation or rolling |
permissions |
object | null | Restricted permissions object, or null for full access |
expires_at |
string | null | ISO 8601 expiry timestamp (set during grace-period rolling) |
last_used_at |
string | null | ISO 8601 timestamp of last API request |
created_at |
string | ISO 8601 creation timestamp |
updated_at |
string | ISO 8601 last-modified timestamp |