Developer Image API v1

Getting started with the Epochal Stock Image API

This guide walks you from a new developer account to a working authenticated request against https://epochalstock.com/api/v1. You will register, subscribe to the single $50 USD/month plan, create a named API key, store it in the environment, and call health plus image search.

Prerequisites

Before you write integration code, make sure you have:

  • A server-side runtime (Node.js, PHP, Python, Go, etc.) that can send HTTPS requests with custom headers
  • Ability to store secrets as environment variables or in a secrets manager (not in git, not in frontend bundles)
  • A company or product contact email for the developer account
  • A PayPal account for the monthly subscription
  • Optional but recommended: curl for quick terminal checks

Browser JavaScript is not a supported client for authenticated calls. CORS is intentionally restricted for catalog endpoints that require a secret key. Your backend should validate input and proxy only the fields your product needs.

Setup steps

Account and billing operations run through the developer portal (management session + CSRF). Catalog traffic uses the Image API base URL with a Bearer key. The two surfaces are separate on purpose.

Option A — instant free trial (fastest): skip registration and billing entirely. POST https://epochalstock.com/api/v1/trial/signup with {"email":"...","app_name":"..."} returns a working es_test_ key immediately — 2,000 requests, 2/minute, 1 month. Continue with step 4 below. Details on the pricing & trial page. The steps that follow are Option B, the paid onboarding.

1. Register a developer account

Create an account with name, company, email, and a password of at least 12 characters. Registration and login use a management session: obtain a CSRF token first, keep the session cookie, and send X-CSRF-Token on state-changing portal requests.

2. Subscribe with PayPal ($50 / month — first month $40)

The paid plan is $50 USD per month for the full image catalog, 30 requests per minute, unlimited serial original downloads, and up to 20 named API keys. First-time subscribers get 20% off the first month ($40) automatically. There is no per-image billing in v1.

Start a subscription from the portal billing flow. Approve it in PayPal. Access becomes available only after PayPal reports the subscription as ACTIVE (webhook-driven activation). Payment failure or suspension moves the account to past_due and blocks catalog access until resolved.

3. Create a named API key

After the subscription is active, create a key with a clear project name (for example cms-production or design-app-staging). The full secret is shown only once at creation time. Epochal Stock stores a keyed hash, not the raw secret. You can create up to 20 named keys per account and revoke any key immediately if a project is compromised.

4. Store the key in the environment

Copy the secret into a secure store and expose it to your process as an environment variable. Recommended name: EPOCHAL_API_KEY. Never commit the key, put it in a mobile app, paste it into support tickets, or embed it in a public repository.

5. Make your first authenticated request

Call GET /health (no key) to confirm connectivity, then GET /images with Authorization: Bearer …. Query-string keys such as ?api_key=… are rejected (query_key_rejected) because URLs leak into logs, proxies, and browser history.

Onboarding path

Register Portal account + strong password
Subscribe PayPal $50/mo · wait for ACTIVE
Create key Named secret · shown once
Env + request Bearer header · server only

Go-live checklist

Before production traffic

  • Developer account registered and verified for login
  • PayPal subscription approved and account status is active
  • At least one named API key created for this deployment
  • Key stored as EPOCHAL_API_KEY (or secrets manager) on the server
  • Key never present in frontend code, mobile binaries, or git history
  • Base URL configured: https://epochalstock.com/api/v1
  • Connect and read timeouts set on HTTP clients
  • 429 / 502 / 503 retries use bounded exponential backoff with jitter
  • Request IDs logged for support (X-Request-ID / meta.request_id)
  • Download tokens treated as secrets until expiry; originals not redistributed as a competing stock library

Environment setup recommendations

Keep configuration boring and explicit. A minimal server environment looks like this (values are placeholders—never commit real secrets):

Environment
# Catalog API (server process only)
EPOCHAL_API_BASE=https://epochalstock.com/api/v1
EPOCHAL_API_KEY=es_live_your_secret_here

# Optional docs-site settings if you self-host this documentation
# EPOCHAL_CACHE_TTL=300
# SITE_BASE_PATH=
  • Use a separate named key per environment (staging vs production) so you can revoke one without downtime elsewhere.
  • Rotate keys periodically and immediately after any suspected exposure.
  • Do not log Authorization headers, download tokens, or full response bodies that might contain signed URLs in long-lived analytics stores.
  • All keys under one account share the 30 req/min budget and the single concurrent original download lease.

Health check

GET /health does not require a Bearer token. Use it to verify DNS, TLS, and service availability before debugging authentication. A healthy response returns HTTP 200; degraded conditions may return 503.

cURL
curl -sS -i "https://epochalstock.com/api/v1/health"

What success looks like

Successful JSON responses wrap payload content in data and attach request metadata under meta. Image list responses include images, total, the effective limit, an opaque next_cursor when more results exist, and an echo of applied filters.

Success envelope
{
  "data": {
    "images": [
      {
        "id": "es_001_example",
        "title": "Golden forest path",
        "width": 6000,
        "height": 4000,
        "tags": ["nature", "trees", "forest"]
      }
    ],
    "total": 1284,
    "limit": 5,
    "next_cursor": "eyJvZmZzZXQiOjV9",
    "filters": {
      "q": "forest",
      "sort": "newest"
    }
  },
  "meta": {
    "request_id": "req_01EXAMPLE"
  }
}

Also inspect response headers on authenticated calls:

  • X-Request-ID — correlation ID for support
  • X-RateLimit-Limit — always 30 for the account window
  • X-RateLimit-Remaining — remaining budget in the current minute
  • X-RateLimit-Reset — unix timestamp when the window resets
  • Retry-After — present on HTTP 429 responses

Common early-integration failures: missing Authorization header (401), inactive subscription (402), and exceeding 30 req/min (429). Full tables live under Limits & Errors.

Security note

Never put your API key in the browser or any public frontend. Secret Bearer keys belong only on trusted servers or serverless backends with locked-down environment variables. Do not ship keys in SPA bundles, browser extensions, client-side config files, or mobile apps that end users can reverse engineer. If a key might have been exposed, revoke it in the portal and create a new named key immediately.

Downloads are designed so the secret key never appears on the binary transfer URL: mint a five-minute token with POST /downloads, then fetch the returned download_url without Authorization. Treat that URL as sensitive until it expires. Details: Downloads and Security & Billing.

Next steps

You have connectivity and a first search. Continue with the guides that match your integration:

Authentication

Bearer format, key lifecycle, revocation, and why query-string keys fail.

Detail & batch

Single-image metadata and POST /images/batch for up to 100 IDs per request.

Downloads

Two-step original delivery, token expiry, and the one-at-a-time concurrency rule.

Tags & stats

Browse normalized tags and monitor catalog size with live counts.

Code examples

Longer copy-paste samples for production-shaped server clients.