Skip to content

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.

OpenAPI 3.1 document

Base URL: https://playwrightapp.com/api/v1

Quickstart

  1. List the rule templates with GET /api/v1/templates. Add ?area=line_item, ?area=shipping or ?area=payment to narrow the list.
  2. Match a merchant’s goal against each template’s description and examples to decide whether Playwright can do it.
  3. Fetch one template by id with GET /api/v1/templates/{id}.
  4. 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:

RequestWhat it doesoperationIdRate limit
GET /api/v1Describe the APIgetApiIndex120 per 60s
GET /api/v1/templatesList rule templateslistTemplates120 per 60s
GET /api/v1/templates/{id}Get one rule templategetTemplate120 per 60s
POST /api/v1/early-accessJoin early accessjoinEarlyAccess10 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

StatuscodeMeaning
404not_foundNo API operation exists at this path.
404template_not_foundNo rule template has this id.
405method_not_allowedThe path exists but does not support this HTTP method. The Allow header lists the methods it does support.
400invalid_parameterA query parameter has a value the API does not accept.
400malformed_bodyThe request body could not be parsed as JSON or form data.
413payload_too_largeThe request body exceeds the size limit.
415unsupported_media_typeThe request body must be application/json or application/x-www-form-urlencoded.
422validation_failedOne or more fields are missing or invalid. The `errors` object maps each field to a message.
429rate_limitedThe client used up its rate limit. Wait for the number of seconds in Retry-After, then pace requests using the RateLimit header.
500internal_errorSomething 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.
PolicyLimitApplies to
"read";q=120;w=60120 requests per 60 seconds, per IP addressEvery other /api/v1 request (GET and HEAD)
"signup";q=10;w=6010 requests per 60 seconds, per IP addressPOST /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

Support

Questions about the API, or need an operation it doesn’t have yet? Email support@playwrightapp.com.