iya.ru
Theme
Sign in Sign up

HTTP API (user & admin)

The agent-swarm API is documented separately in [AGENT_API.md](AGENT_API.md). This page covers the platform API used by the dashboard, integrations and scripts.

  • Base URL: https://iya.ru/api/v1/
  • Specification: GET /api/v1/openapi.json (OpenAPI 3.1, generated from code)
  • Authentication: Authorization: Bearer <api-token>
  • Envelope: { "ok": true, "data": …, "meta": … } / { "ok": false, "error": { … } }
  • Versioning: the major version lives in the path (/api/v1/…). Backwards

compatibility is guaranteed within a major version; breaking changes require a new major and a deprecation window announced in the changelog.

Tokens

Create tokens in Dashboard → API tokens. A token is shown once; only its SHA-256 hash is stored, together with a human-readable prefix (iya_u_9f3a…) so you can recognise it in a list.

Each token carries:

  • scopes — links:read, links:write, stats:read, subdomain:write,

team:read, admin (the last one only for staff roles);

  • an optional IP allowlist (CIDR);
  • an optional expiry;
  • last_used_at / last_used_ip for auditing.

A token outside its scopes or allowlist answers 403 forbidden. Revoking is immediate.

Endpoints

Discovery & health

MethodPathAuthPurpose
GET/api/v1/–API index
GET/api/v1/health–liveness + dependency probe
GET/api/v1/status–version, features, limits, counters
GET/api/v1/openapi.json–OpenAPI 3.1 document
GET/api/v1/errors–error catalogue
GET/api/v1/languages–supported locales
GET/metrics–Prometheus-style metrics

Public read (no auth, owner-controlled)

MethodPathNotes
GET/api/v1/subdomains/{name}public page payload
GET/api/v1/links?subdomain=…public links
GET/api/v1/stats?subdomain=…aggregates, only if the owner enabled them
GET/api/v1/visits?subdomain=…recent visits, only if the list is public

Each of these respects the subdomain's privacy policy: stats_public, stats_show_visits_list, stats_show_ip, stats_show_internal_ip, stats_show_geo, stats_show_ua, stats_show_referrer, stats_show_links, stats_show_owner, stats_publish_delay_sec and stats_max_items. Fields the owner hid are removed server-side, not merely hidden in the UI.

Authenticated

MethodPathScopePurpose
GET/POST/api/v1/linkslinks:read / links:writelist and create links
GET/PATCH/DELETE/api/v1/links/{id}links:*read, update, soft-delete
POST/api/v1/links/{id}/duplicatelinks:writeclone
GET/api/v1/links/{id}/qrlinks:readQR code (SVG/PNG)
GET/api/v1/stats/{scope}/{id}stats:readreport data (subdomain, link, user)
GET/api/v1/visitsstats:readfiltered visit list with cursor pagination
GET`/api/v1/export?format=csv\json\xlsx\pdf`stats:readexport
GET/POST/api/v1/webhookssubdomain:writemanage webhooks
GET/POST/api/v1/tokens–manage API tokens

Tracker (browser beacon)

MethodPathPurpose
GET/POST/tracker/collectconsent-gated telemetry enrichment
POST/tracker/consentrecord a consent decision

The beacon only ever adds client-side signals (time zone, screen, network, capability probes, and — with explicit consent — the LAN IP discovered via WebRTC). It can never change the server-determined ip_public.

Legacy compatibility

The original iya.ru v0 API is preserved so existing integrations keep working:

GET /api/rest.php/ip            → current visitor
GET /api/rest.php/ip/{ip}       → visitor by IP
GET /api/rest.php/visits?limit= → recent visits
GET /api/rest.php/bots          → recent bots
GET /api/rest.php/hacks         → recent attack attempts
GET /api/rest.php/stats         → counters

New code should use /api/v1/…; the v0 shape is frozen and will only receive security fixes.

Pagination

Cursor-based for large collections:

{ "data": { "visits": [ … ] },
  "meta": { "count": 50, "total": 183442, "limit": 50,
            "cursor": "…", "next_cursor": "…", "has_more": true } }

Pass ?cursor=<next_cursor> for the following page. Offset pagination (?page=) is available for human-facing tables only.

Webhooks

Configure them in Dashboard → Account → Event webhooks. Events: visit.new, visit.unique, link.limit_reached, security.suspicious, link.created, link.target_down, agent.task. (Emitters shipped for all except link.target_down — lands with the target-health checker — and agent.task — lands with the swarm follow-ups; both are already accepted subscriptions.) The Test button delivers a webhook.test event outside the subscription.

  • Payload: the same envelope, plus event and delivered_at.
  • Signature: X-Iya-Signature: sha256=<hmac> over the raw body with the

webhook secret. Verify it in constant time.

  • Delivery: exponential backoff, 5 attempts, then the webhook is disabled and

the owner notified. Every attempt is logged (webhook_deliveries).

  • Outbound requests go through the SSRF guard: private ranges, cloud metadata

endpoints and dangerous ports are refused.

Errors and debugging

See [ERRORS.md](ERRORS.md). Every response carries X-Request-Id; the same id appears in meta.request_id and in the server access log, which makes a single request traceable end to end.

Version 2.0.0 · Author: Mikhail Deynekin · icons@Deynekin.com · source: docs/API.md