API docs
tinyping turns an HTTP request into a push notification on your phone. This page has everything you need to send events from your apps.
Quickstart
You need a tinyping account and about two minutes.
- Create a project
A project is one app or service that sends alerts. Create one from your dashboard. - Copy the token
Create a token on the project page and copy it right away, because it is shown only once. Use it in place of tp_YOUR_TOKEN below, and use the project id from the page in place of YOUR_PROJECT_ID. - Send your first event
Run one of the examples below. The event lands in your inbox and arrives as a push notification on every device with alerts turned on.
curl -X POST https://tinyping.app/api/v1/projects/YOUR_PROJECT_ID/events \
-H 'Authorization: Bearer tp_YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"title":"New sign-up","body":"ada@example.com started a trial","kind":"signup","priority":"normal"}'A 201 response with an id means the event was stored.
Authentication
Every request carries a project token in the Authorization header.
Authorization: Bearer tp_YOUR_TOKEN- A token belongs to one project and can only send events to it. Using it on another project returns 403.
- Tokens are shown once when you create them and are stored only as a hash. If you lose one, create a new one.
- Keep tokens on your server or in your CI secrets. Never put one in a browser bundle or a mobile app, because anyone who has it can send alerts to your project.
- To rotate a token, create a new one on the project page, deploy it, then revoke the old one. A revoked token stops working immediately.
Send an event
Send a POST request with a JSON body to your project's events endpoint.
https://tinyping.app/api/v1/projects/YOUR_PROJECT_ID/events| Field | Type | Description |
|---|---|---|
| title | string | The headline of the notification. Up to 120 characters. |
| body | string | More detail, shown under the title. Up to 2,000 characters. |
| url | string | A link attached to the event. It must start with http or https. Up to 2,048 characters. |
| priority | low | normal | high | How important the event is. Defaults to normal. |
| kind | string | A short label for grouping, like signup or backup. Up to 40 characters. |
| tags | string[] | Up to 8 tags, each up to 32 characters. Duplicates are removed. |
Surrounding whitespace is trimmed. The whole request body can be up to 16,384 bytes.
Example request
curl -X POST https://tinyping.app/api/v1/projects/YOUR_PROJECT_ID/events \
-H 'Authorization: Bearer tp_YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"title":"New sign-up","body":"ada@example.com started a trial","kind":"signup","priority":"normal"}'Example response
A successful call returns status 201 with the id and creation time of the stored event.
{
"id": "0b6f2c1e-3d4a-4f5b-9a7c-1e2d3c4b5a69",
"createdAt": "2026-11-11T09:30:00.000Z"
}Errors
Failed requests return a JSON body with a readable error and a stable code. Branch on the code, not on the message.
{
"error": "title: Too small: expected string to have >=1 characters",
"code": "validation_failed",
"issues": [
{
"path": "title",
"message": "Too small: expected string to have >=1 characters"
}
]
}| Status | Code | Meaning | What to do |
|---|---|---|---|
| invalid_json | The body is not valid JSON. | Send a JSON body and set the Content-Type header to application/json. | |
| missing_token | There is no Bearer token in the Authorization header. | Add an Authorization header with Bearer followed by your project token. | |
| invalid_token | The token does not exist. | Check that you copied the whole token, or create a new one. | |
| token_revoked | The token was revoked. | Create a new token on the project page and deploy it. | |
| token_project_mismatch | The token belongs to a different project. | Use a token from the project in the URL, or fix the project id. | |
| project_not_found | No project has this id. | Check the project id in the URL. | |
| payload_too_large | The body is over 16,384 bytes. | Shorten the text fields and send less in each event. | |
| validation_failed | A field is missing or invalid. The issues list gives the path and message for each problem. | Fix the fields listed in issues and send the event again. | |
| rate_limited | This token sent too many events. The Retry-After header and the retryAfter field give the seconds to wait. | Wait that long, then retry. Throttle or batch on your side. | |
| monthly_limit_reached | Your workspace used all of its events for the month. The limit field is your plan's allowance and resetsAt is when the count starts over. | Wait until resetsAt, or upgrade your plan. |
Limits
- Each token can send up to 60 events every 60 seconds. Past that, requests fail with 429 and rate_limited.
- A request body can be up to 16,384 bytes.
- Monthly events are counted for the whole workspace across all its projects, and the count starts over at the beginning of each month in UTC. When it is used up, requests fail with 429 and monthly_limit_reached until the reset.
- Events older than your plan's history are deleted.
| Plan | Events per month | History |
|---|---|---|
| Free | 1,000 | 7 days |
| Pro | 50,000 | 365 days |
Getting alerts on your phone
Install tinyping as an app, then turn on notifications for it.
iPhone and iPad
- Use iOS 16.4 or later. Older versions cannot receive these alerts.
- Open tinyping in Safari, tap Share, then tap Add to Home Screen.
- Open tinyping from its Home Screen icon, not from Safari, and sign in.
- Turn on notifications in the app when it asks, or from its notification settings.
Android
- Open tinyping in Chrome and choose Install app from the menu. You can also keep using it in the browser.
- Allow notifications when Chrome asks, or turn them on in the app's notification settings.
Desktop Chrome
- Open tinyping and click the install icon in the address bar. You can also keep using it in a tab.
- Allow notifications when Chrome asks, or turn them on in the app's notification settings.
If alerts do not show up, check that notifications are allowed for tinyping in your device settings.
Recipes
Copy an example, set the TINYPING_TOKEN environment variable and replace the project id in the URL.
New sign-up from a Node backend
Send an alert from the code that creates the account. The catch keeps a failed alert from breaking the sign-up.
async function notifySignup(user) {
await fetch('https://tinyping.app/api/v1/projects/YOUR_PROJECT_ID/events', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TINYPING_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'New sign-up',
body: user.email,
kind: 'signup',
}),
}).catch(() => {});
}Failed backup from a shell script
The || runs curl only when the backup command fails, so you hear about problems and nothing else.
./backup.sh || curl -X POST https://tinyping.app/api/v1/projects/YOUR_PROJECT_ID/events \
-H "Authorization: Bearer $TINYPING_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"title":"Backup failed","body":"The nightly backup exited with an error","kind":"backup","priority":"high"}'Payment webhook handler
Forward a short summary instead of the full payload. In production, verify the provider's webhook signature before this step.
export async function POST(request) {
const payment = await request.json();
await fetch('https://tinyping.app/api/v1/projects/YOUR_PROJECT_ID/events', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TINYPING_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: `Payment of ${payment.amount} ${payment.currency}`,
body: payment.customer_email,
kind: 'payment',
}),
});
return new Response('ok');
}