Fenestro API v1

Public API

Automate your Fenestro catalog from your own systems.

A clean REST API to create and manage brands, categories and products programmatically. Bearer token auth. Versioned. Rate limited. Built for integrations.

Base URL https://api.fenestro.io/v1

Quickstart

Create your first brand in under a minute.

  1. 1

    Get an API token

    Ask your Fenestro SuperAdmin to generate a token from the admin backoffice (Settings → API). The token is shown once and starts with fen_live_.

  2. 2

    Call the API

    Every request needs an Authorization: Bearer header.

    # Create a brand
    curl -X POST https://api.fenestro.io/v1/brands \
      -H "Authorization: Bearer fen_live_xxxxxxxxxxxx" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Reynaers Aluminium",
        "description": "Belgian aluminium profile manufacturer",
        "display_order": 10
      }'
  3. 3

    Parse the response

    Successful creation returns 201 Created with the new resource.

    {
      "id": 142,
      "name": "Reynaers Aluminium",
      "description": "Belgian aluminium profile manufacturer",
      "image_url": null,
      "display_order": 10,
      "active": true,
      "created_at": "2026-04-23T15:32:11Z"
    }

Authentication

All endpoints (except /v1/health) require a Bearer token.

One token per tenant

Each token is tied to a single Fenestro tenant. All data created with that token belongs to that tenant. No way to cross-target.

Shown once

The token clear value is only displayed at creation time. Only a SHA-256 hash is stored. Lost a token? Revoke it and create a new one.

Revocable

A token can be revoked at any time from the backoffice. Revoked tokens receive 401 revoked_token on every call.

Header format

Authorization: Bearer fen_live_K8dH2pL9mX3vN7qR4tY6wB1zE5cF0aJs

Conventions

  • Versioning — every endpoint lives under /v1/. Breaking changes mean a new version; /v1 stays stable.
  • JSON only — request and response bodies are UTF-8 JSON. Field names are snake_case.
  • Dates — ISO 8601 UTC (2026-04-23T14:32:11Z).
  • IDs — resource IDs are integers; tenant IDs are UUIDs.

Rate limits

Each token is limited to 300 requests per minute. Exceeding the limit returns 429 Too Many Requests with a Retry-After: 60 header.

HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json

{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Limit: 300/minute per token."
}

Error format

All errors share the same shape. Match on error — it's stable. The message is human-readable and may change.

{
  "error": "validation_error",
  "message": "One or more fields are invalid.",
  "details": [
    { "field": "name", "issue": "required" }
  ]
}
400 validation_error

Body missing or fields invalid

401 missing_authentication

No Authorization header

401 invalid_token

Token unknown or malformed

401 revoked_token

Token has been revoked

429 rate_limit_exceeded

More than 300 req/min

500 internal_error

Unexpected server error

Ready to explore?

The full interactive reference lives in Swagger UI — request/response schemas, examples, "try it out".

Open Swagger UI