Offset Orders
An Offset Order represents an order placed on Wren to remove a certain amount of carbon dioxide (or CO₂ equivalents) from the atmosphere using projects in a Portfolio. When you create an offset order, our system records the amount of CO₂ removed and pays the respective project partners for carbon credits at the end of each month.
POST /api/offset-orders — Create offset orders
Creates offset orders by allocating a given number of tons across the projects in a portfolio. Funds are distributed according to the portfolio's allocation percentages.
/api/offset-ordersAuthentication
Required. Use a team API token (recommended) or legacy personal API token via Basic auth or Bearer token. Account (password, Google, or Shopify) required for personal tokens. Test tokens (wren_test_…) return canned responses without DB writes, Stripe charges, or notifications — full validation still runs. See Test mode.
Headers
Content-Type: application/jsonorapplication/x-www-form-urlencoded
Request body
| Attribute | Type | Description & Constraints |
|---|---|---|
tons |
number | Required. Amount of CO₂e to offset in tonnes. |
portfolioId |
number | Optional. Portfolio ID for allocation. Default: Wren Climate Fund. |
note |
string | Optional. Note attached to each order. |
dryRun |
boolean | Optional. If true, no charge is made; returns preview only. |
sendReceiptEmail |
boolean | Optional. If true, sends a receipt email when dryRun is false. |
paymentMethod |
string | Optional. "stripe" (default) or "credits". When "credits", deducts from your credit balance instead of charging Stripe. No $1 minimum when using credits. |
onBehalfOfName |
string | Optional. Name of the end-customer this order is being placed for. Shown as the purchaser on the impact certificate. Max 200 characters. |
onBehalfOfEmail |
string | Optional. Email of the end-customer this order is being placed for. Stored alongside the order; not used for sending email. Max 320 characters. |
Minimum amount
tonsmust be positive.- When
paymentMethodis"stripe"(default): total charge must be at least 100 USD cents ($1). Minimum tons depends on portfoliocost_per_ton. - When
paymentMethodis"credits": no minimum charge — any positivetonsvalue is accepted, as long as you have sufficient credit balance.
Example request
Success response
HTTP 200
id— Stripe charge ID, ornullwhendryRun=trueamountCharged— In the user currency's smallest denomination (e.g. 5000 = $50.00)
When paymentMethod is "credits", the response also includes:
paymentMethod—"credits"creditsRemaining— Remaining credit balance in USD cents after the order
Error responses
- 400 — Invalid payload, missing
tons, charge below minimum, or insufficient credit balance - 403 — Missing/invalid auth or not an account user
GET /api/offset-orders — List your offset orders
Returns the authenticated user's offset orders with aggregate stats.
/api/offset-ordersAuthentication
Required. Use a team API token or legacy personal API token via Basic auth or Bearer token. Test tokens return a small canned sample list.
Request
No body. No query parameters.
Success response
HTTP 200
stats.totalTons— Sum of certified and external-standard offset tonsstats.rank/stats.percentile— User's global ranking (omitted whentotalTonsis 0)offsetOrders— Certified offset orders (snake_case fields)uncertifiedOffsetOrders— Offsets not meeting certified standardsamount_paid_by_customer— USD cents. Typically integer-valued, but sub-cent fractional values can appear on rows from credit-funded sub-dollar orders, where a small charge is split across multiple projects.
Error responses
- 403 — Missing or invalid authentication
GET /api/offset-orders/public — List public offset orders
Returns a curated list of public offset orders for display (e.g. leaderboards, feeds). No authentication required. Data is cached and refreshed hourly.
/api/offset-orders/publicAuthentication
None required.
Request
No body. No query parameters.
Success response
HTTP 200
- Up to 30 orders, sorted by most recent
- Each row aggregates one user's charge per portfolio



