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 reads configuration exclusively from environment variables — there are no config files with secrets checked into the repository. For local development, copy .env.example to .env at the repo root and populate it. For production deployments on ECS Fargate, inject the required variables from Secrets Manager via the task definition. The frontend reads a separate frontend/.env.local file for browser-accessible configuration.

Backend Variables

These variables are read by the FastAPI process at startup. Place them in .env at the repo root.

Required in Production

The following seven variables are enforced at boot time when ENVIRONMENT=production. The process will not start if any of them are missing or blank.
Type: String — asyncpg connection URLThe full connection string used by SQLAlchemy’s async engine. Must use the postgresql+asyncpg:// scheme.
POSTGRES_URL=postgresql+asyncpg://vg_user:vg_pass@localhost:5432/vg_hub
When running inside Docker Compose, replace localhost with the service name postgres:
POSTGRES_URL=postgresql+asyncpg://vg_user:vg_pass@postgres:5432/vg_hub
Docker Compose sets this automatically for the api service using the POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB values.
Type: Fernet key (base64-encoded, 44 characters)Encrypts and decrypts EncryptedJSON columns: suppliers.auth_config and customers.ops_auth_config. The EncryptedJSON SQLAlchemy type decorator in database.py applies AES-128 Fernet encryption transparently on every read and write.Generate a valid key:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
If SECRET_KEY changes after credentials have been stored, every encrypted value in the database becomes permanently unreadable. Rotate this key only through a full re-encryption migration.
Type: String — any high-entropy random stringSigns and verifies auth tokens issued at /api/auth/login. If this value changes, all existing sessions are immediately invalidated and users must log in again.Generate a suitable value:
python -c "import secrets; print(secrets.token_urlsafe(48))"
Type: String — 32+ character random stringAuthenticates n8n-to-FastAPI calls on ingest endpoints (POST /api/ingest/{sid}/...). n8n passes this value in the X-Ingest-Secret header. FastAPI rejects requests where the header is missing or does not match exactly.
python -c "import secrets; print(secrets.token_urlsafe(32))"
This same value must be set in both the FastAPI environment and the n8n container environment. In Docker Compose both services read ${INGEST_SHARED_SECRET} from the same .env file.
The value must match character-for-character between FastAPI and n8n. A mismatch causes all ingest calls to return 403 and sync jobs to fail immediately.
Type: Comma-separated list of URLsControls which browser origins the FastAPI CORS middleware permits. In production this is the definitive allowlist — no wildcard or regex fallback is applied.
ALLOWED_ORIGINS=https://hub.yourdomain.com,https://storefront.yourdomain.com
In development mode (ENVIRONMENT=development), the middleware additionally permits any http://localhost:* or http://127.0.0.1:* origin via regex, so you do not need to enumerate every local port.Default (development only):
ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://127.0.0.1:5173
Type: URL stringBase URL that FastAPI uses to construct webhook trigger URLs pointing at n8n. In Docker Compose this is the internal service URL. In production it is the public or VPC-internal URL of your n8n deployment.
# Docker Compose (internal)
N8N_WEBHOOK_BASE_URL=http://n8n:5678

# Production (public hostname)
N8N_WEBHOOK_BASE_URL=https://n8n.yourdomain.com
Type: URL stringThe FastAPI base URL as seen by the n8n container. n8n workflows read this from $env.API_BASE_URL when constructing HTTP request URLs to the backend.
# Local dev — n8n reaches the host machine
API_BASE_URL=http://host.docker.internal:8000

# Docker Compose — n8n reaches the api service by name
API_BASE_URL=http://api:8000

# Production — public or VPC-internal FastAPI hostname
API_BASE_URL=https://api.yourdomain.com

Optional Backend Variables

Values: development (default) | productionControls three behaviours:
  • Startup check: production mode enforces all required env vars and blocks boot on missing values.
  • CORS: production mode disables the allow_origin_regex localhost fallback; only ALLOWED_ORIGINS entries are permitted.
  • Cookie security: production mode sets Secure and SameSite=Strict on auth cookies.
ENVIRONMENT=production
Type: URL string — default: http://n8n:5678FastAPI uses this URL to call the n8n REST API for workflow listing and trigger-by-ID operations (proxied through /api/n8n/workflows/{id}/trigger).
N8N_API_BASE_URL=http://n8n:5678
Type: StringAPI key for the n8n REST API. Generate from n8n editor → Settings → API. Required if you want to trigger workflows from the admin UI via POST /api/n8n/workflows/{id}/trigger.
N8N_API_KEY=your-n8n-api-key
Type: Full webhook URLThe complete URL of the OPS push webhook in n8n. FastAPI posts to this URL when triggering an OPS push job.
# Development
N8N_PUSH_WEBHOOK_URL=http://n8n:5678/webhook/vg-ops-push-001

# Production
N8N_PUSH_WEBHOOK_URL=https://n8n.yourdomain.com/webhook/vg-ops-push-001
Values: true | unset (default: scheduler enabled)Set to true to prevent the 24-hour background sync scheduler from starting. Useful in environments where syncs are triggered exclusively via n8n cron workflows, or during debugging when you want to eliminate background activity.
DISABLE_SCHEDULER=true
Type: Strings — used by Docker Compose onlyThese variables configure the postgres service and are interpolated into the POSTGRES_URL that Docker Compose passes to the api service. They are not read directly by the FastAPI application.
POSTGRES_USER=vg_user
POSTGRES_PASSWORD=vg_pass
POSTGRES_DB=vg_hub
Type: URL — default shown belowThe PromoStandards directory service endpoint used to auto-discover all 994+ registered suppliers and their endpoint versions.
PS_DIRECTORY_URL=https://services.promostandards.org/WebServiceRepository/WebServiceRepository.svc/json
Type: Strings — optional, SanMar imports onlySanMar product data is fetched via SFTP in addition to SOAP. These variables are only required if you are configuring a SanMar supplier.
SANMAR_SFTP_HOST=ftp.sanmar.com
SANMAR_SFTP_PORT=2200
SANMAR_SFTP_USER=your-sftp-username
SANMAR_SFTP_PASS=your-sftp-password

Frontend Variables

The Next.js frontend reads variables from frontend/.env.local. Only variables prefixed with NEXT_PUBLIC_ are bundled into the browser JavaScript bundle.
Type: URL stringThe FastAPI base URL used by browser-side fetch calls. This must be a URL the end user’s browser can reach — not an internal Docker network hostname.
# Local development
NEXT_PUBLIC_API_URL=http://127.0.0.1:8000

# Production
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
Type: URL stringThe n8n editor URL, used by the admin Workflows page to display workflow links.
NEXT_PUBLIC_N8N_URL=http://localhost:5678
Type: String — n8n workflow IDThe workflow ID of the OPS push workflow, used by the frontend to construct the trigger URL via the n8n proxy.
NEXT_PUBLIC_PUSH_WORKFLOW_ID=vg-ops-push-001
Never prefix server-only secrets with NEXT_PUBLIC_. Any variable with that prefix is embedded verbatim into the compiled browser JavaScript and is visible to all users. Keep SECRET_KEY, JWT_SECRET_KEY, INGEST_SHARED_SECRET, and all database credentials in the backend .env only.

Security Reference

Credential Encryption

All supplier and customer credentials are stored as encrypted JSONB via the EncryptedJSON SQLAlchemy type. The SECRET_KEY Fernet key encrypts these columns transparently on every write and decrypts them on every read. No plaintext credentials ever reach the database.

Ingest Authentication

The INGEST_SHARED_SECRET protects the FastAPI ingest endpoints from unauthorised callers. It is passed as the X-Ingest-Secret header by n8n workflows and validated on every ingest request. n8n and FastAPI must share the exact same value.

JWT Session Tokens

Auth tokens are signed with JWT_SECRET_KEY and stored as HTTP-only cookies. In production mode, cookies are issued with Secure and SameSite=Strict flags. Changing JWT_SECRET_KEY immediately invalidates all active sessions.

CORS Enforcement

In production, ALLOWED_ORIGINS is the sole source of truth for permitted browser origins. The development regex fallback (which allows any localhost port) is disabled when ENVIRONMENT=production.

Minimal .env for Local Development

# .env (repo root)
POSTGRES_URL=postgresql+asyncpg://vg_user:vg_pass@localhost:5432/vg_hub
POSTGRES_USER=vg_user
POSTGRES_PASSWORD=vg_pass
POSTGRES_DB=vg_hub

SECRET_KEY=<output of Fernet.generate_key()>
JWT_SECRET_KEY=<output of secrets.token_urlsafe(48)>
INGEST_SHARED_SECRET=<output of secrets.token_urlsafe(32)>

ENVIRONMENT=development
ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000

API_BASE_URL=http://host.docker.internal:8000
N8N_API_BASE_URL=http://n8n:5678
N8N_WEBHOOK_BASE_URL=http://n8n:5678
N8N_PUSH_WEBHOOK_URL=http://n8n:5678/webhook/vg-ops-push-001
# frontend/.env.local
NEXT_PUBLIC_API_URL=http://127.0.0.1:8000
NEXT_PUBLIC_N8N_URL=http://localhost:5678
Generate all three cryptographic values in one pass before writing your .env:
python -c "
from cryptography.fernet import Fernet
import secrets
print('SECRET_KEY=' + Fernet.generate_key().decode())
print('JWT_SECRET_KEY=' + secrets.token_urlsafe(48))
print('INGEST_SHARED_SECRET=' + secrets.token_urlsafe(32))
"

Build docs developers (and LLMs) love