Using API v1? See what changes in v2, or the v1 docs
Keys
List API keys, and rotate a key with a grace period during which both the old and new keys work.
The examples use IDs from a sample sandbox. Your sandbox has the same people, calendars and events with its own IDs, which GET /v2/sandbox returns. When you're signed in to the dashboard, Try it fills in your IDs and sends the request to your sandbox, never to live data.
List API keys
Returns the app's keys, with their status and, for a rotated key, when it stops working. A live key lists live keys, and a test key lists test keys. Key values are never returned.
Errors
AUTH_INVALID_KEY(401): The API key is missing, unknown or revoked.AUTH_EXPIRED_KEY(401): The API key has expired.AUTH_INSUFFICIENT_SCOPE(403): The API key or session does not have permission to make this request.RATE_LIMIT_EXCEEDED(429): The request rate exceeds this plan's rate limit.RATE_LIMIT_BURST(429): Too many requests were sent in a short period.INTERNAL_ERROR(500): Something went wrong on our end.
Request
curl 'https://api.pyas.io/v2/keys' \ -H "x-api-key: $PYAS_API_KEY"Response
{ "success": true, "data": [], "provider": null, "traceId": "trc_5f2a9c1e7b3d4a6f8e0c2b1d", "meta": {}}Get an API key
In the sandbox: current is the key that sent the request. The API reference sends requests with a key created for the docs, which isn't one of your app's keys. With your own test key, this request returns that key.
Path parameters
- Name
keyId- Type
- string
- Required
- required
- Description
The key's ID, or
currentfor the key that sent the request.
Errors
AUTH_INVALID_KEY(401): The API key is missing, unknown or revoked.AUTH_EXPIRED_KEY(401): The API key has expired.AUTH_INSUFFICIENT_SCOPE(403): The API key or session does not have permission to make this request.RESOURCE_NOT_FOUND(404): The calendar or event was not found.RATE_LIMIT_EXCEEDED(429): The request rate exceeds this plan's rate limit.RATE_LIMIT_BURST(429): Too many requests were sent in a short period.INTERNAL_ERROR(500): Something went wrong on our end.
Request
curl 'https://api.pyas.io/v2/keys/current' \ -H "x-api-key: $PYAS_API_KEY"Response
{ "success": true, "data": { "keyId": "3f7c2a91-5d4e-4b8a-9c6f-2e1d0b7a8c53", "name": "Production", "mode": "live", "scopes": [ "read", "write" ], "status": "active", "last4": null, "expiresAt": null, "graceEndsAt": null, "rotatedFrom": null, "rotatedTo": null, "createdAt": "2026-11-14T20:00:31Z", "seenInBrowser": null }, "provider": null, "traceId": "trc_5f2a9c1e7b3d4a6f8e0c2b1d", "meta": {}}Rotate an API key
Creates a new key with the same name, scopes and mode, and returns its value once in this response. A key can rotate only itself, so send this request with the key that you want to rotate, and use current as the key ID. To rotate a different key, use the dashboard. The old key gets a grace period during which both keys work (default 24 hours, at most 168), so you can deploy the new key without any failed requests. When the grace period ends, the old key stops working. Pyas sends an api_key.expiring webhook 1 hour before the grace period ends, and an api_key.revoked webhook when it ends. A key can be rotated only once.
In the sandbox: Rotates the key that sent the request. The API reference sends requests with a key created for the docs, which can't be rotated. With your own key, the response includes the new key (returned only once), and the old key keeps working for 24 more hours.
Path parameters
- Name
keyId- Type
- string
- Required
- required
- Description
The key's ID, or
currentfor the key that sent the request.
Headers
- Name
Idempotency-Key- Type
- string
- Description
A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.
Body
- Name
graceHours- Type
- integer
- Description
The number of hours that the old key keeps working.
0stops the old key immediately. From 0 to 168.
- Name
expiresInDays- Type
- integer
- Description
The number of days until the new key expires. Defaults to the old key's lifetime, or no expiration if the old key never expired. From 1 to 3650.
Errors
VALIDATION_INVALID_BODY(400): The request body is not valid.AUTH_INVALID_KEY(401): The API key is missing, unknown or revoked.AUTH_EXPIRED_KEY(401): The API key has expired.AUTH_INSUFFICIENT_SCOPE(403): The API key or session does not have permission to make this request.RESOURCE_NOT_FOUND(404): The calendar or event was not found.RESOURCE_CONFLICT(409): The resource was modified or already exists.RATE_LIMIT_EXCEEDED(429): The request rate exceeds this plan's rate limit.RATE_LIMIT_BURST(429): Too many requests were sent in a short period.INTERNAL_ERROR(500): Something went wrong on our end.
Request
curl -X POST 'https://api.pyas.io/v2/keys/current/rotate' \ -H "x-api-key: $PYAS_API_KEY" \ -H "content-type: application/json" \ -d '{ "graceHours": 24}'Response
{ "success": true, "data": { "key": "pyas_sk_live_example", "newKey": { "keyId": "2f660cba-c95f-4314-9466-b494c83efdae", "name": "Production", "mode": "live", "scopes": [ "read", "write" ], "status": "active", "last4": "NzNh", "expiresAt": null, "graceEndsAt": null, "rotatedFrom": "3f7c2a91-5d4e-4b8a-9c6f-2e1d0b7a8c53", "rotatedTo": null, "createdAt": "2026-11-14T20:00:32Z", "seenInBrowser": null }, "previousKey": { "keyId": "3f7c2a91-5d4e-4b8a-9c6f-2e1d0b7a8c53", "name": "Production", "mode": "live", "scopes": [ "read", "write" ], "status": "rotating", "last4": null, "expiresAt": "2026-11-15T20:00:32Z", "graceEndsAt": "2026-11-15T20:00:32Z", "rotatedFrom": null, "rotatedTo": "2f660cba-c95f-4314-9466-b494c83efdae", "createdAt": "2026-11-14T20:00:31Z", "seenInBrowser": null } }, "provider": null, "traceId": "trc_5f2a9c1e7b3d4a6f8e0c2b1d", "meta": {}}