Skip to content
YAS.SH
OpenAPI 3.1.0 · API v1

YAS.SH API

Build, manage, redirect and analyze short links programmatically. Create and manage short links, generate QR codes, access click analytics, manage API keys, and automate supported tools.

Base URL
https://yas.sh/api/v1
API version
v1 · app v3.20.0
Authentication
Bearer token Session cookie
OpenAPI version
OpenAPI 3.1.0
Getting Started

Introduction

The yas.sh API lets you programmatically shorten URLs, generate QR codes, read click analytics, manage API keys and run developer tools. It is RESTful, JSON-based, and follows RFC 9457 for errors.

REST + JSON

Predictable resource URLs and consistent JSON responses. OpenAPI 3.1 contract.

Fast, public, cache-friendly

Public redirect and QR endpoints need no authentication.

Typed, runnable examples

Every endpoint ships copyable cURL, JS, TS and Python examples.

The canonical contract
This reference is generated from the real API and mirrors the OpenAPI 3.1 document served at /api/v1/openapi.

Quick Start

Five steps from zero to your first working short link. Assume nothing — every step is spelled out.

  1. 1

    Create an API key

    Log in to your dashboard and open Account → API Keys. Click Create Key, give it a name, choose its scopes, and create it.
  2. 2

    Store the key securely

    The raw key is shown exactly once. Store it in a server-side environment variable. Send it as Authorization: Bearer yas_live_…. Never expose a key in frontend/browser code.
  3. 3

    Create your first link

    curl -X POST https://yas.sh/api/v1/links \
      -H "Authorization: Bearer yas_live_abc123..." \
      -H "Content-Type: application/json" \
      -d '{"originalUrl":"https://example.com","customAlias":"launch"}'
  4. 4

    Read the response

    201 Created
    {
      "shortCode": "launch",
      "url": "https://yas.sh/launch",
      "link": {
        "id": "clx1abc2def3",
        "shortCode": "launch",
        "customAlias": "launch",
        "originalUrl": "https://example.com",
        "clicks": 0,
        "expiresAt": null,
        "createdAt": "2026-08-08T10:00:00.000Z"
      }
    }
  5. 5

    Open your short link

    Visit https://yas.sh/launch in your browser — it redirects (302) to https://example.com. Done! 🎉

Authentication

There are two ways to authenticate: a session cookie (browser/dashboard) and a Bearer API key (server-to-server). Choose based on where your code runs.

Bearer token

For server-side automation. Create a key in the dashboard or via POST /api/v1/api-keys.

Bearer
curl https://yas.sh/api/v1/links \
  -H "Authorization: Bearer yas_live_abc123..."

Keys are scoped. A key can only call endpoints matching its granted scopes — links:read, links:write, analytics:read. Missing scope returns 403.

Session cookie

For the dashboard/browser. Logging in sets an httpOnly yas_session cookie (30 days, Lax). Sends it automatically. Sessions hold all scopes.

Cookie
# Login sets the yas_session cookie for subsequent requests
curl -X POST https://yas.sh/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"correct-horse-battery-staple"}' \
  -c cookies.txt

curl https://yas.sh/api/v1/links -b cookies.txt
API key management is session-only
Creating, listing and revoking keys (/api/v1/api-keys) requires a browser session — an API key can never mint or enumerate other keys. Use the cookie for those.

API Keys

A step-by-step key lifecycle: create, copy, store, use, rotate and revoke.

  1. 1
    Create. Dashboard → API Keys → Create, or POST /api/v1/api-keys (session required).
  2. 2
    Copy. The raw key is returned exactly once in the response — copy it immediately.
  3. 3
    Store. Save it in a server-side environment variable. Never in client-side code or git.
  4. 4
    Use. Send Authorization: Bearer yas_live_... on every protected request.
  5. 5
    Rotate. Create a new key, switch your app over, then revoke the old one.
  6. 6
    Revoke. DELETE /api/v1/api-keys/{id} — immediate and permanent.
Shown once
Only the SHA-256 hash is stored. A lost key must be revoked and recreated.
Max 10 keys
Hitting the limit returns 403 LIMIT_REACHED.
Revocation
Revoking a key makes it fail with 401 immediately. Existing sessions are unaffected.

Errors

All error responses use RFC 9457 (application/problem+json). Every error carries type, title, status, code and a human-readable detail.

application/problem+json
{
  "type": "https://yas.sh/docs/errors#validation_error",
  "title": "Validation failed",
  "status": 400,
  "code": "VALIDATION_ERROR",
  "detail": "customAlias: 3-30 chars: a-z 0-9 - _"
}

type is a stable URI that resolves to the error’s documentation. code is the machine-readable key — match on it in your error handling.

StatusCodeMeaningCommon causeHow to fix
400VALIDATION_ERRORThe request body or query is invalid — a field failed validation.Missing required field, malformed URL, invalid alias pattern, expiresAt in the past, or bad JSON.Check the detail message for the exact field and constraint, fix it, and retry.
401UNAUTHORIZEDYou are not authenticated, or the credential is invalid.Missing/invalid Bearer token, expired API key, or no session cookie on a protected endpoint.Attach a valid Authorization: Bearer yas_live_... header (or a session cookie), or log in first.
403FORBIDDENAuthenticated but not allowed to perform the action.The API key lacks the required scope, the request came from an untrusted origin (CSRF), or a plan/key limit was reached (LIMIT_REACHED).Grant the required scope, call from a trusted origin, or reduce usage / upgrade the plan.
404NOT_FOUNDThe resource does not exist, or you do not own it.Wrong id, deleted resource, or an id owned by another user (returned as 404 to avoid leaking existence).Verify the id and that the resource belongs to your account.
409CONFLICTThe request conflicts with the current state.Alias/short code already taken, or another unique-constraint conflict.Choose a different alias/email. Create Link may include suggestions in the response.
413PAYLOAD_TOO_LARGEThe request body exceeds the allowed size.Body over the endpoint limit (e.g. links 20 KB, tools 64 KiB).Reduce the payload size and retry.
429RATE_LIMITEDYou have exceeded a rate limit.Too many requests in the window (see Rate Limits).Wait for the Retry-After period, respect the RateLimit-* headers, and use exponential backoff.
500INTERNAL_ERRORSomething went wrong on the server.An unexpected server error. Details are never leaked to the client.Retry with backoff; if it persists, contact support with the request details.

Rate Limits

Limits are enforced per-user and/or per-IP depending on the endpoint. On a 429, honor the Retry-After header and back off exponentially.

EndpointScopeLimitHeaders
POST /api/v1/linksper-user60 / minX-RateLimit-*
POST /api/v1/linksper-IP120 / minX-RateLimit-*
POST /api/v1/auth/loginper-IP15 / minRetry-After
POST /api/v1/auth/registerper-IP20 / minRetry-After
POST /api/v1/api-keysper-user10 / minRetry-After
POST /api/v1/tools/:slugper-IP60 / minRetry-After
/{code} password attemptsper-IP10 / minRetry-After

Plan-specific API request limits (daily)

API-key authenticated requests are counted against your plan's daily API quota. Session (cookie) requests from the dashboard are not counted.

PlanAPI Requests
Free100 / day
Starter1,000 / day
Pro10,000 / day
Business100,000 / day
EnterpriseUnlimited
Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers for API-key requests.
429 example
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 60

{
  "type": "https://yas.sh/docs/errors#rate_limited",
  "title": "Rate Limited",
  "status": 429,
  "code": "RATE_LIMITED",
  "detail": "Too many requests",
  "retryAfter": 60
}
What clients should do
Read Retry-After (seconds) and wait before retrying. Implement exponential backoff with jitter. Do not retry immediately or in tight loops — you will only extend the block.

Pagination

List endpoints (e.g. GET /api/v1/links) use cursor pagination. The response returns a nextCursor — pass it to get the next page.

Request 1
GET
GET /api/v1/links?limit=20
200 OK
{
  "data": [ /* up to 20 links */ ],
  "nextCursor": "clx1abc2def3"
}
Request 2 — use nextCursor
GET
GET /api/v1/links?limit=20&cursor=clx1abc2def3
200 OK
{
  "data": [ /* the next page */ ],
  "nextCursor": "clx9zyx8wvu7"   // null when there are no more pages
}
limit defaults to 20 and accepts 1–100. A nextCursor of null means you have reached the last page.

Idempotency

POST /api/v1/links supports an optional Idempotency-Key header so safe retries never create duplicate links.

First call
curl -X POST https://yas.sh/api/v1/links \
  -H "Authorization: Bearer yas_live_abc123..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-launch" \
  -d '{"originalUrl":"https://example.com","customAlias":"launch"}'
Retry — same key
# Same request, same Idempotency-Key — returns the existing link, no duplicate.
curl -X POST https://yas.sh/api/v1/links \
  -H "Authorization: Bearer yas_live_abc123..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-launch" \
  -d '{"originalUrl":"https://example.com","customAlias":"launch"}'
When the same key is reused for an identical create, the existing link is returned (200, with idempotent: true) instead of a new one. The key is checked before the plan limit, so retries never 403 on the free-tier cap. Max length 128 characters.

Security

Keep your keys safe. These practices prevent the most common leaks.

  • Never commit API keys to version control.
  • Never expose secret API keys in client-side JavaScript.
  • Use environment variables for all secrets.
  • Rotate compromised keys immediately.
  • Revoke unused keys.
  • Use least-privilege scopes (e.g. links:read only).

Type Generation & SDK

Generate typed clients from the canonical OpenAPI 3.1 document.

openapi-typescript
# Generate TypeScript types from the live spec
npx openapi-typescript https://yas.sh/api/v1/openapi -o sdk.ts

The spec is a single authoritative document, so code generation stays in sync with the API. Any OpenAPI 3.x code generator (openapi-typescript, openapi-generator, etc.) works against /api/v1/openapi.

Tutorials

Real-world examples

Task-oriented recipes. Each links to the relevant endpoint for the full parameter reference.

Create a short link with a custom alias

Set customAlias to control the short code.

curl
curl -X POST https://yas.sh/api/v1/links \
  -H "Authorization: Bearer yas_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{"originalUrl":"https://example.com","customAlias":"launch"}'

Create an expiring link

Set expiresAt to a future ISO 8601 datetime. The link stops redirecting after that time (returns 410).

curl
curl -X POST https://yas.sh/api/v1/links \
  -H "Authorization: Bearer yas_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{"originalUrl":"https://example.com/sale","expiresAt":"2026-12-31T23:59:59Z"}'

Create a password-protected link

Set password (8–128 chars). Visitors must submit it to be redirected.

curl
curl -X POST https://yas.sh/api/v1/links \
  -H "Authorization: Bearer yas_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{"originalUrl":"https://example.com/private","password":"super-secret"}'

Update a link's destination

PATCH the link with a new originalUrl — the short code stays the same.

curl
curl -X PATCH https://yas.sh/api/v1/links/clx1abc2def3 \
  -H "Authorization: Bearer yas_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{"originalUrl":"https://example.com/new-destination"}'

List links with search

Search matches originalUrl, shortCode, customAlias and title.

curl
curl "https://yas.sh/api/v1/links?search=launch&limit=20" \
  -H "Authorization: Bearer yas_live_abc123..."

Get account analytics

Totals, daily series, and top breakdowns for the last 30 days.

curl
curl "https://yas.sh/api/v1/analytics/overview?days=30" \
  -H "Authorization: Bearer yas_live_abc123..."

Get analytics for one link

Lifetime click count and recent events for a single link.

curl
curl "https://yas.sh/api/v1/analytics/clx1abc2def3?days=30" \
  -H "Authorization: Bearer yas_live_abc123..."

Generate a QR code

Public endpoint — returns PNG (or SVG) image bytes, no auth needed.

curl
curl "https://yas.sh/api/v1/qr?url=https://yas.sh/demo&size=512" -o qr.png

Create an API key

Requires a session cookie. The raw key is returned exactly once.

curl
curl -X POST https://yas.sh/api/v1/api-keys \
  -H "Cookie: yas_session=..." \
  -H "Content-Type: application/json" \
  -d '{"name":"ci","scopes":["links:read","links:write","analytics:read"]}'

Revoke an API key

Permanent and immediate — requests using the key start failing with 401.

curl
curl -X DELETE "https://yas.sh/api/v1/api-keys/clk1abc" \
  -H "Cookie: yas_session=..."
Reference

API Reference

Every endpoint, verified against the live implementation. Use the sidebar or search to jump to any endpoint.

Public · no auth Public · Bearer token Bearer · Session cookie Cookie ·Session only Session only

redirect

GET/{code}Public · no auth

Redirect

Resolve a short code to its destination with an HTTP 302.

https://yas.sh/{code}

What this endpoint does

This is the public redirect endpoint — the core of yas.sh. Visiting a short code (or custom alias) returns a 302 to the destination. It is public and requires no authentication. Expiry, per-link passwords and bot filtering are enforced here. Click events are recorded asynchronously.

Parameters

NameLocationTypeRequiredDescription
codepathstringYesThe short code or custom alias.
· 330 · e.g. launch
passwordquerystringNoRequired when the link is password-protected.

Request examples

# A plain redirect:
curl -i https://yas.sh/launch

# A password-protected link:
curl -i "https://yas.sh/secret?password=MyPass123"

Response 302 Found

Redirect to the destination URL.

302 Found
HTTP/1.1 302 Found
Location: https://example.com?utm_source=newsletter
Content-Type: text/plain; charset=utf-8

Response fields

FieldTypeNullableAlways returnedDescription
LocationheaderNoYesThe destination URL to follow.
bodystringNoNoA short text body. Click events are recorded asynchronously and bot clicks are filtered.

Errors

StatusCodeMeaning
401PASSWORD_REQUIREDThe link is password-protected and no/incorrect password was provided (an HTML form is returned).
404NOT_FOUNDNo link exists for this code.
410GONEThe link has expired or its click limit was reached.
429RATE_LIMITEDToo many password attempts (10/min).
POST/{code}Public · no auth

Unlock Protected Link

Submit a link password to follow a protected redirect.

https://yas.sh/{code}

What this endpoint does

Submits the password for a protected link (form-encoded). On success the server responds with a 302 to the destination, same as the plain GET.

Parameters

NameLocationTypeRequiredDescription
codepathstringYesThe short code or custom alias.
· 330

Request body

Request body (application/x-www-form-urlencoded)
Required: password

Request examples

curl -X POST https://yas.sh/secret \
  -d "password=MyPass123"

Response 302 Found

Redirect to the destination.

302 Found
HTTP/1.1 302 Found
Location: https://example.com

Response fields

FieldTypeNullableAlways returnedDescription
LocationheaderNoYesThe destination URL.

Errors

StatusCodeMeaning
401PASSWORD_REQUIREDIncorrect password.
404NOT_FOUNDNo link exists for this code.
410GONEThe link has expired.
429RATE_LIMITEDToo many password attempts (10/min).

analytics

GET/api/v1/analytics/overviewBearer tokenscope: analytics:read

Analytics Overview

Aggregate click analytics for the current user.

https://yas.sh/api/v1/analytics/overview

What this endpoint does

Returns bot-filtered click totals, a daily click series, and top countries, devices, browsers and referrers for the last N days. This is the same data shown on the dashboard. Breakdowns run as database-side aggregations.

Parameters

NameLocationTypeRequiredDescription
daysqueryintegerNo
default: 30
Window in days.
· 190 · e.g. 30

Request examples

curl "https://yas.sh/api/v1/analytics/overview?days=30" \
  -H "Authorization: Bearer yas_live_abc123..."

Response 200 OK

Aggregate analytics for the requested window.

200 OK
{
  "totalLinks": 42,
  "totalClicks": 1248,
  "series": [
    { "date": "2026-07-10", "clicks": 41 },
    { "date": "2026-07-11", "clicks": 63 }
  ],
  "breakdowns": {
    "country": [{ "name": "US", "value": 320 }],
    "device": [{ "name": "mobile", "value": 800 }],
    "browser": [{ "name": "chrome", "value": 700 }],
    "referrer": [{ "name": "google", "value": 410 }]
  }
}

Response fields

FieldTypeNullableAlways returnedDescription
totalLinksintegerNoYesNumber of links owned by the user.
totalClicksintegerNoYesBot-filtered clicks in the window.
seriesarrayNoYesOne entry per day in the window (zero-filled).
series[].datestringNoYesDay (YYYY-MM-DD).
series[].clicksintegerNoYesClicks on that day.
breakdownsobjectNoYesTop countries/devices/browsers/referrers.
breakdowns.countryarrayNoYesTop countries as { name, value }.
breakdowns.devicearrayNoYesTop devices as { name, value }.
breakdowns.browserarrayNoYesTop browsers as { name, value }.
breakdowns.referrerarrayNoYesTop referrers as { name, value }.

Errors

StatusCodeMeaning
401UNAUTHORIZEDNo valid Bearer token or session cookie.

qr

GET/api/v1/qrPublic · no auth

Generate QR Code

Render a QR code as PNG or SVG.

https://yas.sh/api/v1/qr

What this endpoint does

Generates a QR code image from a URL. This endpoint is public and requires no authentication. It returns raw binary image data (PNG) or an SVG string — it does not return JSON. Responses are cached for 1 hour.

Parameters

NameLocationTypeRequiredDescription
urlquerystringYesContent to encode (http/https only).
· e.g. https://yas.sh/demo
sizequeryintegerNo
default: 512
Output size in pixels.
Allowed: 128 | 256 | 512 | 1024
formatquerystringNoOutput format.
Allowed: png (default) | svg

Request examples

# PNG (default):
curl "https://yas.sh/api/v1/qr?url=https://yas.sh/demo&size=512" -o qr.png

# SVG:
curl "https://yas.sh/api/v1/qr?url=https://yas.sh/demo&format=svg" -o qr.svg

Response 200 OK

Image bytes (image/png) or SVG document (image/svg+xml).

200 OK
HTTP/1.1 200 OK
Content-Type: image/png
Cache-Control: public, max-age=3600

<binary PNG data>

<!-- or, with &format=svg -->
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512">...</svg>

Response fields

FieldTypeNullableAlways returnedDescription
bodybinaryNoYesRaw PNG image or SVG string. Never JSON.
Content-TypeheaderNoYesimage/png or image/svg+xml.

Errors

StatusCodeMeaning
400VALIDATION_ERRORurl is missing or not an http/https URL.

auth

POST/api/v1/auth/registerPublic · no auth

Register

Create an account and start a session.

https://yas.sh/api/v1/auth/register

What this endpoint does

Creates a user account and sets a yas_session cookie (httpOnly, 30 days, Lax). Rate limited to 20/min per IP. Passwords must be at least 8 characters and not on the common-password denylist.

Request body

Request body (application/json)
Required: email, password, name

Request examples

curl -X POST https://yas.sh/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"correct-horse-battery-staple","name":"You"}' \
  -c cookies.txt

Response 201 Created

Account created and session started.

201 Created
{
  "user": {
    "id": "clxuser1",
    "email": "you@example.com",
    "name": "You",
    "role": "user"
  }
}

Response fields

FieldTypeNullableAlways returnedDescription
userobjectNoYesThe created user.
user.idstringNoYesUser id.
user.emailstringNoYesEmail address.
user.namestringNoYesDisplay name.
user.rolestringNoYesRole (user).

Errors

StatusCodeMeaning
400VALIDATION_ERRORInvalid email, weak/too-common password, or missing name.
201CREATEDSame success shape whether the address is new or already registered (anti-enumeration).
429RATE_LIMITEDExceeded 20/min per IP.
POST/api/v1/auth/loginPublic · no auth

Login

Authenticate with email and password and start a session.

https://yas.sh/api/v1/auth/login

What this endpoint does

Authenticates a user and sets a yas_session cookie. Uses anti-enumeration timing so the response time does not reveal whether an email exists. Rate limited to 15/min per IP.

Request body

Request body (application/json)
Required: email, password

Request examples

curl -X POST https://yas.sh/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"correct-horse-battery-staple"}' \
  -c cookies.txt

Response 200 OK

Authenticated and session cookie set.

200 OK
{
  "user": {
    "id": "clxuser1",
    "email": "you@example.com",
    "name": "You",
    "role": "user"
  }
}

Response fields

FieldTypeNullableAlways returnedDescription
userobjectNoYesThe authenticated user.

Errors

StatusCodeMeaning
401UNAUTHORIZEDInvalid credentials.
429RATE_LIMITEDExceeded 15/min per IP.
GET/api/v1/auth/meSession cookie

Get Current User

Return the authenticated user.

https://yas.sh/api/v1/auth/me

What this endpoint does

Returns the currently authenticated user. When logged out it returns { user: null } with a 200 — useful as a lightweight probe without triggering 401 noise.

Request examples

curl "https://yas.sh/api/v1/auth/me" \
  -H "Cookie: yas_session=..."

Response 200 OK

The authenticated user, or user: null when logged out.

200 OK
{
  "user": {
    "id": "clxuser1",
    "email": "you@example.com",
    "name": "You",
    "role": "user"
  }
}

Response fields

FieldTypeNullableAlways returnedDescription
userobjectYesYesThe user, or null when not authenticated.
PATCH/api/v1/auth/meSession cookie

Update Profile

Update the signed-in user's name and/or email.

https://yas.sh/api/v1/auth/me

What this endpoint does

Updates the current user's name and/or email. Requires a session cookie (not an API key).

Request body

Request body (application/json)
Optional: name, email

Request examples

curl -X PATCH https://yas.sh/api/v1/auth/me \
  -H "Cookie: yas_session=..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Your New Name"}'

Response 200 OK

The updated user.

200 OK
{
  "user": {
    "id": "clxuser1",
    "email": "you@example.com",
    "name": "Your New Name",
    "role": "user"
  }
}

Response fields

FieldTypeNullableAlways returnedDescription
userobjectNoYesThe updated user.

Errors

StatusCodeMeaning
400VALIDATION_ERROREmpty name or invalid email.
401UNAUTHORIZEDNot authenticated.
409CONFLICTEmail already in use.
POST/api/v1/auth/change-passwordSession cookie

Change Password

Verify the current password and set a new one.

https://yas.sh/api/v1/auth/change-password

What this endpoint does

Verifies the current password, sets a new password, and signs out all other sessions. Requires a session cookie.

Request body

Request body (application/json)
Required: currentPassword, newPassword

Request examples

curl -X POST https://yas.sh/api/v1/auth/change-password \
  -H "Cookie: yas_session=..." \
  -H "Content-Type: application/json" \
  -d '{"currentPassword":"old-password","newPassword":"new-password"}'

Response 200 OK

Password changed.

200 OK
{
  "ok": true
}

Response fields

FieldTypeNullableAlways returnedDescription
okbooleanNoYesAlways true on success.

Errors

StatusCodeMeaning
400VALIDATION_ERRORWrong current password or invalid input.
401UNAUTHORIZEDNot authenticated.
429RATE_LIMITEDRate limited.
POST/api/v1/auth/logoutSession cookie

Logout

Destroy the session and clear the session cookie.

https://yas.sh/api/v1/auth/logout

What this endpoint does

Destroys the current session and clears the yas_session cookie.

Request examples

curl -X POST https://yas.sh/api/v1/auth/logout \
  -H "Cookie: yas_session=..."

Response 200 OK

Session destroyed.

200 OK
{
  "ok": true
}

Response fields

FieldTypeNullableAlways returnedDescription
okbooleanNoYesAlways true on success.

keys

GET/api/v1/api-keysSession only

List API Keys

List the current user's API keys.

https://yas.sh/api/v1/api-keys

What this endpoint does

Lists the user's API keys. The raw key is never returned — only a prefix, scopes and metadata. This endpoint requires a browser session (an API key cannot list keys).

Request examples

curl "https://yas.sh/api/v1/api-keys" \
  -H "Cookie: yas_session=..."

Response 200 OK

List of API keys.

200 OK
{
  "data": [
    {
      "id": "clk1abc",
      "name": "production",
      "prefix": "yas_live_abc1...",
      "scopes": "links:read,links:write,analytics:read",
      "lastUsedAt": "2026-08-08T09:00:00.000Z",
      "createdAt": "2026-08-01T12:00:00.000Z"
    }
  ]
}

Response fields

FieldTypeNullableAlways returnedDescription
dataarrayNoYesArray of API key metadata objects.
data[].idstringNoYesKey id.
data[].namestringNoYesHuman-friendly key name.
data[].prefixstringNoYesPrefix used for identification. The full key is never returned.
data[].scopesstringNoYesComma-separated scopes granted to the key.
data[].lastUsedAtstringYesNoLast use timestamp, or null.

Errors

StatusCodeMeaning
401UNAUTHORIZEDSession authentication required.
POST/api/v1/api-keysSession only

Create API Key

Create a yas_live_ key. The raw key is shown exactly once.

https://yas.sh/api/v1/api-keys

What this endpoint does

Creates a new API key. Only the SHA-256 hash is stored server-side; the raw key (yas_live_...) is returned in this response exactly once and cannot be retrieved again. Maximum 10 keys per user. Requires a browser session.

Request body

Request body (application/json)
Required: name
Optional: scopes
scopes defaults to links:read,links:write,analytics:read. Unknown scopes are dropped. A key may be scoped down to a single scope.

Request examples

curl -X POST https://yas.sh/api/v1/api-keys \
  -H "Cookie: yas_session=..." \
  -H "Content-Type: application/json" \
  -d '{"name":"production","scopes":["links:read","links:write"]}'

Response 201 Created

Key created. The raw key is returned once.

201 Created
{
  "id": "clk1abc",
  "key": "yas_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "prefix": "yas_live_a1b2...",
  "name": "production",
  "scopes": "links:read,links:write",
  "warning": "Copy now — shown once"
}

Response fields

FieldTypeNullableAlways returnedDescription
idstringNoYesKey id.
keystringNoYesThe raw API key. Returned exactly once — store it immediately.
prefixstringNoYesPrefix for identification.
namestringNoYesKey name.
scopesstringNoYesComma-separated granted scopes.
warningstringNoYesReminder that the key is shown once.

Errors

StatusCodeMeaning
400VALIDATION_ERRORname is required or invalid.
401UNAUTHORIZEDSession authentication required.
403LIMIT_REACHEDAPI key limit (10) reached.
DELETE/api/v1/api-keys/{id}Session only

Revoke API Key

Permanently revoke an API key.

https://yas.sh/api/v1/api-keys/{id}

What this endpoint does

Permanently revokes an API key, making it invalid immediately. This cannot be undone. Requires a browser session and ownership of the key.

Parameters

NameLocationTypeRequiredDescription
idpathstringYesKey id (CUID).

Request examples

curl -X DELETE "https://yas.sh/api/v1/api-keys/clk1abc" \
  -H "Cookie: yas_session=..."

Response 200 OK

The key was revoked.

200 OK
{
  "ok": true
}

Response fields

FieldTypeNullableAlways returnedDescription
okbooleanNoYesAlways true on success.

Errors

StatusCodeMeaning
401UNAUTHORIZEDSession authentication required.
404NOT_FOUNDKey does not exist or is not owned by you.

tools

POST/api/v1/tools/{slug}Public · no auth

Run Tool

Execute a developer utility server-side.

https://yas.sh/api/v1/tools/{slug}

What this endpoint does

Executes one of the utility tools server-side (e.g. hash-calculator, base64-text, uuid-generator, url-encoder, case-converter). Each tool has its own contract. Tools that are browser-only by design for security (e.g. link-checker — SSRF risk) return HTTP 409 with code CLIENT_ONLY_TOOL; they can never be executed through the API. Public and rate limited to 60/min per IP.

Parameters

NameLocationTypeRequiredDescription
slugpathstringYesThe tool slug.

Request body

Request body (application/json)
Optional: input, mode, algo
Tool-specific fields. Input is capped at 64 KiB. See /docs/tools for each tool's contract.

Request examples

curl -X POST https://yas.sh/api/v1/tools/hash-calculator \
  -H "Content-Type: application/json" \
  -d '{"input":"hello","algo":"sha256"}'

Response 200 OK

Tool output.

200 OK
{
  "slug": "hash-calculator",
  "algo": "sha256",
  "result": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}

Response fields

FieldTypeNullableAlways returnedDescription
slugstringNoYesThe tool slug that was run.
resultstringNoYesThe tool's output.
algostringNoNoPresent for hashing tools.
codestringNoNoCLIENT_ONLY_TOOL when the tool is browser-only.
toolstringNoNoThe tool slug that cannot be executed.
executionModestringNoNo'client' for browser-only tools.
apiAvailablebooleanNoNofalse for browser-only tools.

Errors

StatusCodeMeaning
400VALIDATION_ERRORInvalid input for the tool.
404NOT_FOUNDUnknown tool slug.
409CLIENT_ONLY_TOOLThe tool is browser-only (SSRF / File API) and cannot run server-side. GET metadata reports executionMode "client" and apiAvailable false.
429RATE_LIMITEDExceeded 60/min per IP.
GET/api/v1/tools/{slug}Public · no auth

Get Tool Metadata

Inspect a tool's contract.

https://yas.sh/api/v1/tools/{slug}

What this endpoint does

Returns machine-readable metadata about a tool: executionMode (client/server/hybrid), apiAvailable (false for browser-only tools, with reason), methods, inputLimit, level, worksOffline and relatedTools.

Parameters

NameLocationTypeRequiredDescription
slugpathstringYesThe tool slug.

Request examples

curl "https://yas.sh/api/v1/tools/hash-calculator"

Response 200 OK

Tool metadata.

200 OK
{
  "slug": "hash-calculator",
  "methods": ["POST"],
  "inputLimit": 65536,
  "hashAlgorithms": ["md5", "sha1", "sha256", "sha384", "sha512"],
  "docs": "https://yas.sh/docs/api#tools"
}

Response fields

FieldTypeNullableAlways returnedDescription
slugstringNoYesThe tool slug.
methodsarrayNoYesSupported HTTP methods.
inputLimitintegerNoYesMaximum input size in bytes (65536).
hashAlgorithmsarrayNoNoAllowed hash algorithms (hashing tools).

System

GET/api/healthPublic · no auth

Liveness Check

Public liveness probe.

https://yas.sh/api/health

What this endpoint does

Public liveness probe. Returns minimal { status: "ok" } only and discloses no internal details. Use /api/health/ready for a readiness check that also verifies the database.

Request examples

curl -i https://yas.sh/api/health

Response 200 OK

Service is alive.

200 OK
{
  "status": "ok"
}

Response fields

FieldTypeNullableAlways returnedDescription
statusstringNoYesAlways "ok" when the process is up.

Errors

StatusCodeMeaning
500INTERNAL_ERRORService unavailable.
GET/api/health/readyPublic · no auth

Readiness Check

Liveness plus database readiness.

https://yas.sh/api/health/ready

What this endpoint does

Readiness probe that verifies the database and configuration, returning a status and a map of per-check results.

Request examples

curl -i https://yas.sh/api/health/ready

Response 200 OK

Service is ready (database reachable).

200 OK
{
  "status": "ready",
  "checks": { "database": "ok" }
}

Response fields

FieldTypeNullableAlways returnedDescription
statusstringNoYes"ready" or "not_ready".
checksobjectNoYesPer-dependency check results.

Errors

StatusCodeMeaning
503INTERNAL_ERRORA dependency (e.g. database) is unavailable.
Resources

Resources

The OpenAPI 3.1 specification is the source of truth for this documentation.

No undocumented endpoints
Every route in /api/v1/openapi is documented on this page, and every page example was verified against the implementation — including the HTTP method and URL.
Opýtajte sa YAS
🍪 Cookies a súkromie. Nevyhnutné cookies slúžia na prihlásenie, jazyk a motív. Google AdSense sa načíta až po voľbe Prijať všetko. reCAPTCHA sa používa na prihlásení a v kontaktnom formulári. Ako Google používa údaje: https://policies.google.com/technologies/partner-sites zásady cookies · ochrana údajov.
Nastavenia