Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/VisualGraphxLLC/API-HUB/llms.txt

Use this file to discover all available pages before exploring further.

API-HUB uses two separate authentication mechanisms depending on who is calling the API. The admin interface (browser and Next.js frontend) authenticates with a JWT stored in an httponly cookie. Internal machine-to-machine calls from n8n workflows authenticate with a shared secret header instead, keeping credentials out of request bodies entirely.

Roles

RoleAccess
vg_adminFull access to all endpoints and all customers
customer_adminScoped to a specific customer_id; cannot access other customers’ data or admin endpoints

First-time setup

Before any user exists, call the setup endpoint to create the first vg_admin account. This endpoint returns 409 Conflict the moment any user record exists in the database — it is intentionally a one-shot operation.
Call POST /api/auth/setup exactly once, immediately after deployment. Once any user exists, this endpoint is permanently locked.
curl -X POST https://your-hub.example.com/api/auth/setup \
  --cookie-jar cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "change-me-now-12chars"
  }'
Request body
email
string
required
Email address for the first admin account. Normalized to lowercase.
password
string
required
Minimum 12 characters, maximum 256 characters.
Response — 201 Created
id
string (UUID)
Unique identifier for the created user.
email
string
Normalized email address.
role
string
Always vg_admin for the setup endpoint.
customer_id
string | null
null for vg_admin accounts.
is_active
boolean
true for newly created users.
Error responses
StatusDetail
409 Conflict"Admin already configured" — at least one user already exists
409 Conflict"Email already registered" — race condition on concurrent requests

Login

Exchange email and password for an httponly session cookie. The cookie is automatically set on the response and sent back by the browser on every subsequent request.
curl -X POST https://your-hub.example.com/api/auth/login \
  --cookie-jar cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "your-password"
  }'
email
string
required
Registered email address. Case-insensitive.
password
string
required
Account password.
Response — 200 OK Returns the UserRead object and sets the auth_token cookie.
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "email": "admin@example.com",
  "role": "vg_admin",
  "customer_id": null,
  "is_active": true
}
Error responses
StatusDetail
401 Unauthorized"Invalid credentials" — wrong email, wrong password, or inactive account
The cookie name is auth_token. It is httponly, samesite=lax, and secure in production. You cannot read it from JavaScript.

Logout

Clears the auth_token cookie. After this call the session is invalid.
curl -X POST https://your-hub.example.com/api/auth/logout \
  --cookie cookies.txt
Response — 204 No Content No body. The Set-Cookie header instructs the browser to delete auth_token.

Current user

Returns the user associated with the current session cookie. Useful for bootstrapping the UI or checking which role is active.
curl https://your-hub.example.com/api/auth/me \
  --cookie cookies.txt
Response — 200 OK
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "email": "admin@example.com",
  "role": "vg_admin",
  "customer_id": null,
  "is_active": true
}
Error responses
StatusDetail
401 UnauthorizedMissing or invalid auth_token cookie

User management

vg_admin users can create and manage other accounts. All user-management endpoints require a valid vg_admin session cookie.

Create a user

curl -X POST https://your-hub.example.com/api/auth/users \
  --cookie cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "email": "store@customer.com",
    "password": "secure-password-12ch",
    "role": "customer_admin",
    "customer_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }'
email
string
required
Email address for the new user. Must be unique.
password
string
required
Minimum 12 characters, maximum 256 characters.
role
string
default:"customer_admin"
Either "vg_admin" or "customer_admin". Defaults to "customer_admin".
customer_id
string (UUID)
Required when role is "customer_admin". Must be null for "vg_admin".
Response — 201 Created — returns the UserRead object. Error responses
StatusDetail
401 UnauthorizedNot authenticated
409 Conflict"Email already registered"
422 Unprocessable Entitycustomer_admin without customer_id, or vg_admin with customer_id

List users

curl https://your-hub.example.com/api/auth/users \
  --cookie cookies.txt
Returns an array of UserRead objects ordered by created_at descending.

Delete a user

curl -X DELETE https://your-hub.example.com/api/auth/users/{user_id} \
  --cookie cookies.txt
Error responses
StatusDetail
400 Bad Request"Cannot delete your own account"
404 Not FoundUser not found

Internal API authentication (n8n → FastAPI)

n8n workflows that call internal FastAPI endpoints do not use cookies. Instead, they pass the shared secret configured in your .env file as an HTTP header.
curl -X POST https://your-hub.example.com/api/customers/{id}/pricing/quote \
  -H "X-Ingest-Secret: your-ingest-shared-secret" \
  -H "Content-Type: application/json" \
  -d '{ "product_id": "...", "qty": 12 }'
The X-Ingest-Secret value must match INGEST_SHARED_SECRET in your server’s environment. Requests with a missing or incorrect header receive 401 Unauthorized.
Endpoints that require X-Ingest-Secret are:
EndpointPurpose
POST /api/customers/{id}/pricing/quoteMarked-up price with storefront overrides
GET /api/push/{customer_id}/product/{product_id}/payloadOPS-ready push payload
GET /api/push/{customer_id}/product/{product_id}/ops-variantsSize/price bundle for OPS push loop
GET /api/push/{customer_id}/product/{product_id}/ops-optionsProduct options for OPS push
Never expose X-Ingest-Secret-gated endpoints on a public storefront or to end-user clients. They return pricing rules and markup percentages that are internal business data.

Error reference

StatusWhen it occurs
401 UnauthorizedNo auth_token cookie, expired cookie, or invalid X-Ingest-Secret
400 Bad RequestAttempting to delete your own account
409 ConflictDuplicate email, or setup called after users exist
422 Unprocessable EntityInvalid request body (role/customer_id mismatch, password too short)

Build docs developers (and LLMs) love