TinyThis API Docs

Use bearer API keys to create short links, upload hosted files, and fetch raw textual web responses through predictable JSON endpoints.

Version v1 Bearer API keys JSON + multipart
Base URL https://www.tinythis.com/api/v1

Authentication

Every API endpoint requires a bearer API key and an Accept: application/json header. Raw keys are only shown once when created and are stored hashed at rest.

Authorization: Bearer tt_live_xxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json
POST/files

Upload a hosted file

Upload a file with multipart form data. Files are private by default; private uploads do not return a permanent direct storage URL.

Request: fileRequired. jpg, jpeg, png, webp, gif, pdf, txt, or csv; maximum 1024KB.
Request: visibilityOptional private or public. Defaults to private.
Rate limit30 requests per minute per API key.
Private deliveryurl is the TinyThis short URL. Each visit creates a tracked temporary signed storage URL using the configured Spaces/CDN hostname.
Public deliveryurl and direct_url are permanent storage/CDN URLs that do not require signing.
Trackingshort_url is always available and tracked. Requests to a public direct_url bypass TinyThis and cannot be tracked.
curl -X POST https://www.tinythis.com/api/v1/files \
  -H "Authorization: Bearer tt_live_your_api_key" \
  -H "Accept: application/json" \
  -F "file=@invoice.pdf" \
  -F "visibility=private"

Private response

{
  "data": {
    "id": "0199...",
    "original_name": "invoice.pdf",
    "mime_type": "application/pdf",
    "size_bytes": 843221,
    "short_code": "abc1234",
    "visibility": "private",
    "url": "https://tinythis.com/f/abc1234",
    "short_url": "https://tinythis.com/f/abc1234",
    "direct_url": null,
    "created_at": "2026-10-17T10:00:00.000000Z"
  }
}

Public response

{
  "data": {
    "id": "0199...",
    "original_name": "image.webp",
    "mime_type": "image/webp",
    "size_bytes": 128400,
    "short_code": "def5678",
    "visibility": "public",
    "url": "https://cdn.example.com/hosted-files/2026/10/17/file.webp",
    "short_url": "https://tinythis.com/f/def5678",
    "direct_url": "https://cdn.example.com/hosted-files/2026/10/17/file.webp",
    "created_at": "2026-10-17T10:00:00.000000Z"
  }
}
POST/fetches

Fetch a textual URL

Fetch a public HTTP or HTTPS URL with GET and receive the raw textual response body inside JSON.

Request: urlRequired public HTTP or HTTPS URL using port 80 or 443; maximum 4,096 characters.
Request: modeOptional optimize or best. Defaults to optimize.
Request: freshOptional boolean. Defaults to false; true bypasses the cache.
Mode: optimizeTry direct fetching first. A hostname is routed directly only after its response matches the external result by more than 90%; direct routes are verified again weekly.
Mode: bestUse the configured external fetch service immediately.
CacheSuccessful responses are private to your user and cached for 30 minutes.
ContentTextual responses only, up to 4MB.
CostThe external request cost is returned exactly as reported by the upstream service. Initial or weekly direct verification can incur this cost; cached results cost 0.
Response200 OK with response headers, UTF-8 body, source, timing, cache, and cost information.
curl -X POST https://www.tinythis.com/api/v1/fetches \
  -H "Authorization: Bearer tt_live_your_api_key" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","mode":"optimize","fresh":false}'
{
  "success": true,
  "data": {
    "request_id": "01...",
    "url": "https://example.com",
    "status_code": 200,
    "headers": {"content-type": ["text/html; charset=UTF-8"]},
    "body": "<html>...</html>",
    "content_type": "text/html; charset=UTF-8",
    "source": "direct",
    "origin": "direct",
    "mode": "optimize",
    "cache_hit": false,
    "cost": "0",
    "duration_ms": 184,
    "fetched_at": "2026-10-17T10:00:00.000000Z"
  }
}

Errors

401Missing, revoked, expired, or invalid API key.
422Validation failed, including unsupported file type or file too large.
429Rate limit exceeded.
502The target or external fetch service could not return a usable textual response.

Authentication errors use success and message. Validation errors use Laravel's standard message and field-keyed errors object.

{
  "message": "The selected visibility is invalid.",
  "errors": {
    "visibility": ["The selected visibility is invalid."]
  }
}

Fetch failures return the request ID when one was created:

{
  "success": false,
  "message": "The target could not return a usable textual response.",
  "request_id": "0199..."
}