Developer Documentation
API-first. OpenAPI is truth. Every endpoint has curl / JS / TS / Python examples. Bilingual, modular, production-ready.
30 seconds from clone to first short link.
macOS & Oracle Linux 9 — Node ≥22.13, pnpm, Sharp, Prisma.
Env, database, theme tokens, and feature flags.
DATABASE_URL, SESSION_SECRET, BASE_URL, REDIS_URL.
Docker, Coolify, standalone Next, Nginx + headers.
OpenAPI 3.1, SDK, pagination, idempotency.
Cookie + Bearer yas_live_, scopes, rotation.
Fuse.js global (⌘K), blog/tool/docs indexed.
Shorten → redirect → analytics pipeline.
MDX co-located, hero/cover/thumb, i18n EN/AR RTL.
app, components/ui, lib, prisma, blog, docs, public.
Add feature = add folder, never UI→DB.
Oracle Linux 9 checklist, TLS, backups.
Common errors, logs, health checks.
Pricing, limits, RPO, support SLA.
Oracle Linux 9 runbook: proxy, TLS, monitoring, backups, recovery.
Getting started, feature tour, tutorials, troubleshooting.
Getting Started
Clone, env, install, DB, dev — 30 seconds.
cp .env.example .env # Set SESSION_SECRET and a unique SEED_ADMIN_PASSWORD (never use examples) # SEED_ADMIN_PASSWORD="$(openssl rand -base64 24)" pnpm install --frozen-lockfile bash scripts/copy-blog-images.sh pnpm db:push SEED_ADMIN_EMAIL=admin@localhost SEED_ADMIN_PASSWORD="$SEED_ADMIN_PASSWORD" pnpm db:seed pnpm dev # http://localhost:3000 → sign in with the email/password YOU set above
Installation
pnpm -v # 9.12.3
openssl version # OpenSSL 3.x
dnf install openssl vips + nodesource.Configuration
All config via env + next.config.mjs + CSS vars.
app/globals.css :root --brand/--bg + components/theme-provider.tsx 7 palettes.next.config images.remotePatterns locked to yas.sh / unsplash / cdn. AVIF/WebP.Environment Variables
Never commit real secrets. .env.example is placeholder.
Deployment
Three options — local build, Docker, Coolify.
pnpm build && pnpm start # or docker compose up -d # or Coolify on Oracle Linux 9 — see docs/10_DEPLOYMENT.md
Standalone when BUILD_STANDALONE=true — copies minimal deps for Docker.
API Guide
Base /api/v1 • OpenAPI 3.1 at /api/v1/openapi • Errors application/problem+json.
Authentication
Cookie: yas_session httpOnly Secure SameSite Lax — for dashboard.
Bearer: Authorization: Bearer yas_live_… — for servers, auto hashed (SHA-256), lastUsedAt tracked.
Scopes: links:read,links:write,analytics:read. Rotate via /api/v1/api-keys show-once, 10 max.
Search
Global ⌘K opens Fuse.js index of pages/tools/blogs. Endpoint /api/search/index serves blog slugs.
Link Intelligence
Shorten (random base62 7 chars + alias) → 302 redirect (lookup cacheable, optional Valkey) → ClickEvent (geo/device/referrer, bot filtered) → analytics rollup.
Blog System
See Blog Guide. Co-located blog/content/<slug>/index.mdx + hero.webp, auto SSG, sanitized marked, JSON-LD, i18n EN/AR RTL, sticky TOC, progress bar.
Project Structure
app/ Next.js (marketing, dashboard, blog/[slug], docs, api/v1, [code], status, case-studies) components/ui/ Card/Badge/Button/Input + blog-progress/theme-provider/search lib/ api-helpers, api-sdk (UI→REST), auth, prisma, utils, validators, tools-def blog/content/ MDX + hero/cover/thumb per post (EN + AR) prisma/ schema.prisma + seed.ts public/blog-img/ served images (copied via script) scripts/ smoke.sh, security-smoke.sh, copy-blog-images.sh (POSIX) docs/ markdown + BLOG_GUIDE.md
Development Workflow
- Add feature = add folder (
app/tools/[slug]+lib/tools-def) — no core edits. - UI never imports Prisma — only
lib/api-sdk.ts → REST /v1. - Theme via CSS vars — change 2 vars to rebrand.
- Blog via file system — no registry.
- Test:
pnpm build+bash scripts/smoke.sh+BASE= prod bash scripts/security-smoke.sh.
Production Deployment (Oracle Linux 9)
sudo dnf install -y openssl vips # Node 22 LTS via nodesource, pnpm 11.20.0 via corepack (Node 22.13+ required) cp .env.example .env # edit pnpm install --frozen-lockfile pnpm db:push && pnpm db:seed bash scripts/copy-blog-images.sh pnpm build pnpm start # behind Nginx with CSP (next.config headers)
Nginx: proxy + HSTS, 4GB RAM recommended for build, 1GB runtime.
Troubleshooting
BUILD_STANDALONE=true pnpm build or 4GB instance.openssl version must be 3.x; prisma generate on postinstall./^[a-z0-9-]+$/, file index.mdx, run copy script.Deployment
Self-host yas.sh: Docker, Coolify, or standalone Next behind Nginx with TLS. Operational runbook is available to operators — see the deploy/ and docs/ folders in the repo.
User Guide
Getting started, the full feature tour, tutorials, FAQ, and troubleshooting for end users.
FAQ
50 links, 1k clicks/mo, 1 API key. Pro 5k/100k, Business 50k/1M.
Documented in the operations runbook (see docs/15). Backups are an operator responsibility; retention and encryption depend on deployment configuration.
Target response via Contact; formal SLAs are agreed per contract for paid/Enterprise plans.
EN + AR RTL supported, dir auto, locale frontmatter.
About the YAS.SH documentation
This section documents the YAS.SH platform APIs: link shortening and management, the tools API, monitoring, and the authentication model that governs all of them. It is reference material rather than a tutorial, organised so you can find the endpoint, its parameters, its response shape and its error codes without reading anything you do not need.
The tools API reference is generated from the same machine-readable contracts that drive the tool pages themselves. That means an example on a tool page and the contract in the reference cannot drift apart — they are the same data rendered twice, and a contract test fails the build if a documented parameter stops matching the handler.
What is documented here
Tools API
POST /api/v1/tools/:slug for every tool that supports programmatic execution, with parameters, types, defaults, an example request and the exact response shape.
Link API
Creating, updating, expiring and querying short links, including custom slugs, expiry rules and click analytics.
Authentication
How API keys are issued and scoped, how they are passed, and what happens when a key is revoked or a rate limit is reached.
Errors and limits
The error envelope, the status codes each endpoint can return, and the input size and rate limits that apply.
How to use it
Every endpoint is documented with a cURL example you can paste directly into a terminal, plus JavaScript and Python equivalents. The examples use real parameter values rather than placeholders, so a copied command runs and returns a result you can compare against the documented response.
Where an endpoint has behaviour that is easy to get wrong — a size cap, a mode parameter that changes the response shape, a tool that exists on the site but deliberately has no API — it is called out at that endpoint rather than buried in a general notes section.
Frequently asked questions
Do I need an API key to use the tools API?
The tools endpoints are usable without authentication within rate limits intended for interactive and light automated use. Higher-volume use and the link and monitoring APIs require a key issued from your account.
Why do some tools have no API endpoint?
Because executing them server-side would let an anonymous caller make arbitrary outbound requests from our infrastructure, which is a server-side request forgery risk, or because they depend on a browser API that has no server equivalent. Those tools are marked and the reason is stated.
What is the maximum request size?
Tool endpoints accept up to 64 KB of input per request. Larger payloads should be chunked, or processed with the browser-based version of the tool where one exists.
How are errors returned?
As a JSON envelope with a machine-readable code and a human-readable message, alongside the appropriate HTTP status. The error codes for each endpoint are listed with that endpoint.