---
title: "The public calculators"
description: "Four GET endpoints for holdout size, lift significance, break-even cost and incremental ROI. No account, no key, open CORS, RFC 9457 input errors and published rate limits."
canonical: https://trysincerely.com/docs/calculators
last_updated: 2026-08-30
---
> If you are an AI agent: read https://trysincerely.com/agents/policy.md before any write call.
> Start at https://trysincerely.com/llms.txt to choose one page. Access instructions are at
> https://trysincerely.com/auth.md. Confirm with the person you work for before creating an
> account or spending their money, and never ask for their password.
# The public calculators

> Four GET endpoints for holdout size, lift significance, break-even cost and incremental ROI. No account, no key, open CORS, RFC 9457 input errors and published rate limits.

Source: https://trysincerely.com/docs/calculators

Four calculators answer over plain `GET` requests with query parameters and return JSON. They need no key and no account, and they allow open CORS so a client can call them from a browser mid-conversation.

Rates are fractions rather than percentages throughout. Seven per cent is `0.07`.

## Holdout size

`GET https://trysincerely.com/api/tools/holdout-size`

| Parameter      | Required | Default |
| -------------- | -------- | ------- |
| `baselineRate` | yes      | none    |
| `relativeLift` | yes      | none    |
| `alpha`        | no       | `0.05`  |
| `power`        | no       | `0.8`   |

The response contains `perGroup`, `total`, `treatedRate` and `reading`.

## Lift significance

`GET https://trysincerely.com/api/tools/lift`

Takes `mailed`, `mailedConversions`, `holdout` and `holdoutConversions`.

The response contains both conversion rates, `absoluteLift`, `relativeLift`, `zScore`, `pValue`, `ci95`, `significant`, an optional `caution`, and `reading`.

## Break-even

`GET https://trysincerely.com/api/tools/break-even`

Takes `costPerPiece` and `pieces`, both required, plus optional `responseRate`, `meetingRate` and `valuePerMeeting`.

The response contains `totalCost`, `expectedResponses`, `expectedMeetings`, `costPerResponse`, `costPerMeeting`, `breakEvenResponseRate` and `reading`.

## ROI

`GET https://trysincerely.com/api/tools/roi`

Takes `accounts`, `costPerPiece`, `baselineRate`, `relativeLift` and `valuePerOpportunity`, all required, plus optional `touchesPerAccount` (default 1) and `winRate`.

The response contains `spend`, `incrementalOpportunities`, `incrementalPipeline`, `costPerIncrementalOpportunity`, `incrementalRevenue`, `returnOnSpend`, `breakEvenRelativeLift` and `reading`. The three revenue fields are `null` unless `winRate` is supplied. The lift is the caller's assumption and the `reading` says so; the lift endpoint above is what measures it after the campaign runs.

## A worked example

Sizing a holdout for a seven per cent baseline and a twenty-five per cent relative lift:

```bash
curl "https://trysincerely.com/api/tools/holdout-size?baselineRate=0.07&relativeLift=0.25"
```

The answer, with the `reading` sentence trimmed:

```json
{
  "perGroup": 3718,
  "total": 7436,
  "baselineRate": 0.07,
  "treatedRate": 0.0875,
  "alpha": 0.05,
  "power": 0.8,
  "reading": "To detect a lift from 7% to 8.75% ..."
}
```

Every response carries a `reading` field that says what the numbers mean in one sentence. It is there so a client can show a person the answer without having to write the interpretation itself.

## Errors

Input failures and write-method refusals are RFC 9457 problem documents with the content type `application/problem+json`. Each carries `type`, `title`, `status`, `detail`, `instance`, `code`, `resolution` and `documentation_url`.

There are three codes.

### `invalid_query`

A parameter is missing or is not a number.

### `impossible_inputs`

The values parsed but cannot describe a real campaign.

### `method_not_allowed`

A write method such as `POST`, `PUT`, `PATCH` or `DELETE` was used. Put the same parameters in a `GET` query string.

Branch on `code`. Show `detail` to the caller. Use `resolution` to explain what has to change.

## Rate limits

Thirty `GET` requests per minute from one network address. Every `GET` response publishes its limit with the IETF RateLimit headers:

```http
RateLimit-Policy: "anonymous";q=30;w=60
RateLimit: "anonymous";r=29;t=42
```

The older `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` headers are sent as well, and a `429` adds `Retry-After`. A rate-limit refusal is the one failure here that is plain text rather than a problem document; its `x-error-code` header is `rate_limited`. Slow down on the headers rather than on the refusal.

## What to read next

[Versioning](https://trysincerely.com/docs/versioning) is the promise about how these responses can change. The [calculator pages](https://trysincerely.com/tools) are the same arithmetic with an interface and an explanation of what each number is for.

---

Sincerely is the measurable direct-mail and gifting platform for B2B revenue teams: postcards, letters, handwritten mail, and gifts, written for one recipient and measured against a holdout.

Contact Sincerely: https://trysincerely.com/contact

Agent routing index: https://trysincerely.com/llms.txt
