Playwright Checkout Rules developer guide: public API
Playwright’s public API answers two questions for developers, agencies and AI agents: which checkout rules can Playwright build, and how does someone join early access to the Shopify Functions edition.
It is a small, read-mostly JSON API over HTTPS. There are no API keys to create and no sandbox to set up: every GET request works from a browser, curl or an agent right away, and repeating a sign-up is safe.
Base URL: https://playwrightapp.com/api/v1
Quickstart
- List the rule templates with GET /api/v1/templates. Add ?area=line_item, ?area=shipping or ?area=payment to narrow the list.
- Match a merchant’s goal against each template’s description and examples to decide whether Playwright can do it.
- Fetch one template by id with GET /api/v1/templates/{id}.
- When a person asks to join early access, POST their own email address to /api/v1/early-access.
Authentication
None. The public API needs no API key, token or account, and read endpoints allow requests from any origin (CORS). Rules for a specific store are created inside the Playwright app in the Shopify admin and are not available through this API.
Endpoints
Every operation, with its operationId in the OpenAPI document:
| Request | What it does | operationId | Rate limit |
|---|---|---|---|
GET /api/v1 | Describe the API | getApiIndex | 120 per 60s |
GET /api/v1/templates | List rule templates | listTemplates | 120 per 60s |
GET /api/v1/templates/{id} | Get one rule template | getTemplate | 120 per 60s |
POST /api/v1/early-access | Join early access | joinEarlyAccess | 10 per 60s |
Example requests
List the shipping templates (first one shown)
curl -i 'https://playwrightapp.com/api/v1/templates?area=shipping'HTTP/2 200
Content-Type: application/json
RateLimit-Policy: "read";q=120;w=60
RateLimit: "read";r=119;t=60
{
"templates": [
{
"id": "shipping.ShippingDiscount",
"area": "shipping",
"name": "Shipping Discount",
"description": "Apply a shipping discount based on certain criteria",
"examples": [
"Spend $50 or more and get free shipping",
"10% off all DHL shipping rates"
],
"categories": [
"Discount Rates"
]
}
],
"count": 7
}Get one template
curl 'https://playwrightapp.com/api/v1/templates/line_item.BuyXGetX'HTTP/2 200
Content-Type: application/json
{
"template": {
"id": "line_item.BuyXGetX",
"area": "line_item",
"name": "Buy One Get One",
"description": "Buy certain items to receive a discount on other items",
"examples": [
"Buy one shirt, get one free",
"Buy 2 shirts, get a hat free"
],
"categories": [
"Buy One Get One"
]
}
}Join early access (only with the person’s consent)
curl -X POST 'https://playwrightapp.com/api/v1/early-access' \
-H 'Content-Type: application/json' -H 'Accept: application/json' \
-d '{"email":"merchant@example.com","shopDomain":"example-store.myshopify.com","interests":["promotions","shipping"]}'HTTP/2 201
Content-Type: application/json
RateLimit-Policy: "signup";q=10;w=60
RateLimit: "signup";r=9;t=60
{
"status": "joined",
"message": "You’re on the list. We’ll email merchant@example.com when early access opens."
}An error
curl 'https://playwrightapp.com/api/v1/templates/line_item.Nope'HTTP/2 404
Content-Type: application/problem+json
{
"type": "https://playwrightapp.com/openapi.json#/x-problem-types/template_not_found",
"title": "Template not found",
"status": 404,
"detail": "There is no rule template with id \"line_item.Nope\".",
"instance": "/api/v1/templates/line_item.Nope",
"code": "template_not_found",
"resolution": "List valid ids with GET https://playwrightapp.com/api/v1/templates. Ids look like \"line_item.BuyXGetX\" and are case-sensitive."
}Over the rate limit
curl -i 'https://playwrightapp.com/api/v1/templates'HTTP/2 429
Content-Type: application/problem+json
Retry-After: 42
RateLimit-Policy: "read";q=120;w=60
RateLimit: "read";r=0;t=42
{
"type": "https://playwrightapp.com/openapi.json#/x-problem-types/rate_limited",
"title": "Too many requests",
"status": 429,
"detail": "This client has used all 120 requests allowed every 60 seconds under the \"read\" policy.",
"instance": "/api/v1/templates",
"code": "rate_limited",
"resolution": "Wait 42 seconds (the Retry-After header) before sending another request, and pace requests using the RateLimit header. Limits are listed at https://playwrightapp.com/developers#rate-limits."
}Errors
Errors use RFC 9457 problem details with Content-Type application/problem+json. Each problem has a stable, machine-readable code and a resolution that says how to fix the request. Don’t retry a 4xx error without changing the request; a 429 or 500 can be retried later.
Error codes
| Status | code | Meaning |
|---|---|---|
| 404 | not_found | No API operation exists at this path. |
| 404 | template_not_found | No rule template has this id. |
| 405 | method_not_allowed | The path exists but does not support this HTTP method. The Allow header lists the methods it does support. |
| 400 | invalid_parameter | A query parameter has a value the API does not accept. |
| 400 | malformed_body | The request body could not be parsed as JSON or form data. |
| 413 | payload_too_large | The request body exceeds the size limit. |
| 415 | unsupported_media_type | The request body must be application/json or application/x-www-form-urlencoded. |
| 422 | validation_failed | One or more fields are missing or invalid. The `errors` object maps each field to a message. |
| 429 | rate_limited | The client used up its rate limit. Wait for the number of seconds in Retry-After, then pace requests using the RateLimit header. |
| 500 | internal_error | Something went wrong on our side. |
Rate limits
Requests are limited per client IP address. Every response carries the IETF RateLimit-Policy and RateLimit headers, so you can pace requests before you hit the limit:
RateLimit-Policy: the quota for this endpoint: the policy name, q requests per w seconds.RateLimit: what is left: r requests remaining, t seconds until the window resets.Retry-After: on a 429 response only: seconds to wait before the next request.
| Policy | Limit | Applies to |
|---|---|---|
"read";q=120;w=60 | 120 requests per 60 seconds, per IP address | Every other /api/v1 request (GET and HEAD) |
"signup";q=10;w=60 | 10 requests per 60 seconds, per IP address | POST /api/v1/early-access |
Over the limit, the API answers 429 Too Many Requests with a rate_limited problem. Wait for Retry-After seconds, then continue at a pace the RateLimit header allows. CORS clients can read all three headers.
Versioning and deprecation
The version is part of the URL: this is v1, served at /api/v1. New fields and new operations can be added to v1 at any time, so ignore fields you don’t recognise.
Breaking changes ship as a new version under a new path. Before a v1 operation is retired, its responses carry Deprecation and Sunset headers with the dates, and the change is announced on this page and in the OpenAPI document.
Machine-readable resources
- OpenAPI 3.1 document: every operation, schema, error code and header
- API index: links to each operation
- llms.txt: when and how AI agents should use Playwright
- llms-full.txt: every page and the full template catalog in one file
- Every page on this site is also available as Markdown: send
Accept: text/markdown.
Support
Questions about the API, or need an operation it doesn’t have yet? Email support@playwrightapp.com.