shiply.now

API reference

Every public endpoint, request shape, and error code

Base URL: https://shiply.now. All bodies are JSON. The machine-readable spec lives at /openapi.json; a plain-text agent guide at /llms.txt.

Authentication

Pass Authorization: Bearer shp_… for owner operations. Publish without it for anonymous (24 h) sites.

Publishing

POST /api/v1/publish

Create a site (or a new version of one).

FieldTypeNotes
filesarray, required1–1000 entries of { path, size, contentType?, hash? }
files[].pathstringrelative path, no ..; index.html serves at /
files[].sizeintbytes
files[].hashstringoptional lowercase sha256 hex — enables hash-skip
spaModebooleanserve index.html for unknown paths
ttlSecondsintanonymous only; capped at 86400
claimTokenstringupdate an existing anonymous site
viewerobject{ title?, description?, ogImage? }

Returns slug, siteUrl, upload.{versionId, uploads[], skipped[], finalizeUrl, expiresInSeconds}, and for anonymous creates: claimToken, claimUrl, expiresAt.

POST /api/v1/publish/{slug}/finalize

Body { "versionId": "…" }. Verifies every object was uploaded (server-copies hash-skipped files), then flips the site live atomically. 409 conflict if uploads are missing or the version was already finalized.

POST /api/v1/publish/{slug}/uploads/refresh

Body { "versionId": "…" }. Re-presigns upload URLs for a still-pending version.

POST /api/v1/publish/{slug}/claim

Body { "token": "…" }, auth required (key or session). Adopts an anonymous site: permanent, owned, claim token cleared.

Site management (owner auth)

EndpointAction
GET /api/v1/publisheslist your sites
GET /api/v1/publish/{slug}site detail + version history
PATCH /api/v1/publish/{slug}/metadata{ title?, spaMode?, addedToProfile? }
DELETE /api/v1/publish/{slug}delete site + all stored files

Variables (owner auth)

Encrypted key/value store for your agents' third-party credentials. Values are AES-256-GCM encrypted at rest; they are readable only by you and are never injected into published sites.

EndpointAction
GET /api/v1/variableslist (values masked; add ?reveal=1 for plaintext)
PUT /api/v1/variables{ name, value } — upsert; name is UPPER_SNAKE ≤64 chars, value ≤8 KiB
DELETE /api/v1/variables/{name}delete

Agent onboarding

EndpointAction
POST /api/auth/agent/request-code{ email } → emails a 6-digit code (30 s cooldown)
POST /api/auth/agent/verify-code{ email, code }{ apiKey } (code single-use, 10 min)

Profiles

EndpointAction
GET /api/v1/profile/sites?handle=public: a profile's sites
PATCH /api/v1/profileowner: { useProfile?, autoAddToProfile? }
PATCH /api/v1/profile/usernameowner: { username }

Errors

Every error is { "error": { "code", "message" } }.

CodeHTTPMeaning
invalid_request400malformed body, bad path, bad code
unauthorized401missing/invalid key or session
payment_required402plan limit reached (sites/drives/handles/domains) or a paid feature (analytics, password/invite-only) — upgrade
forbidden403not allowed (e.g. non-public read/insert on Site Data)
not_found404unknown slug/version/profile, bad claim token
conflict409uploads incomplete, version not pending, handle taken
rate_limit_exceeded429e.g. requesting codes too fast
service_unavailable503temporary failure (e.g. email delivery)