---
title: "Buy a browser session with a machine payment"
method: POST
path: "/mpp/browsers"
tags: ["Browsers"]
---

# Buy a browser session with a machine payment

`POST /mpp/browsers`

## Request

- Base URL: `https://api.onkernel.com`
- URL: `https://api.onkernel.com/mpp/browsers`
- Auth: none required

Buys a stealth headful browser for the duration in the offer with a Machine Payments Protocol (MPP) payment, without a Kernel account. A request without an `Authorization: Payment` credential gets a 402 challenge; the paid retry returns the browser and a `Payment-Receipt` header. A challenge can be paid until its `expires` time, 30 minutes after it is issued by default. A challenge buys one browser. Resending the same paid credential is intentional and safe: it returns the same browser without charging again until the session expires, even after the challenge has expired, so an agent can retry after a timeout. After the session expires it gets a 402 with a fresh challenge and `code: session_expired`. A different payment for a challenge that was already charged is rejected with a 402 before any charge.

## Request body

- object
  - `email` string, email: Optional address for the Stripe receipt. When omitted, the billing email shared with the payment token is used, if any. A malformed address is rejected with a 400 before any challenge or charge.

## Response `200`

The purchased browser session.

- object
  - `access` object, required
    - `type` 'session_urls', required
  - `browser_live_view_url` string
  - `cdp_ws_url` string, required
  - `created_at` string, date-time, required
  - `duration_minutes` integer, required
  - `expires_at` string, date-time, required
  - `headless` boolean, required
  - `payment` object, required
    - `amount` integer, required: Amount in cents
    - `currency` string, required
    - `reference` string, required: Stripe PaymentIntent ID
  - `session_id` string, required
  - `stealth` boolean, required
  - `webdriver_ws_url` string, required

## Other responses

- `400`: The request body is not a JSON object, or `email` is malformed.
- `402`: Payment required. The `WWW-Authenticate` header carries a fresh Payment challenge; the body is RFC 9457 problem details. When the session this credential bought has expired, the problem type is `invalid-challenge` with `code: session_expired` and `expires_at`.
- `429`: Too many requests from this client.
- `503`: Paid browsers are unavailable, at capacity, or the browser could not be created (payment refunded).

## Changes

- **2026-09-29** `d0ad464764f9`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/onkernel/apis/kernel-api/changes/mpp/browsers/post.md)

---

[API](https://skmtc.dev/onkernel/apis/kernel-api.md) - [All operations](https://skmtc.dev/onkernel/apis/kernel-api/llms.txt) - [OpenAPI document](https://skmtc.dev/onkernel/apis/kernel-api/revisions/0f6cf4f58fe6?raw)
