FOTOhub.app developer console grows into a full creative infrastructure layer

FOTOhub Press Team, FOTOhub.app · · 9 min read

FOTOhub's API console gains real AWS S3 storage with enterprise controls, output routing straight into a customer's own bucket, signed webhooks, and a much bigger documentation site. A look at the infrastructure layer under FOTOhub Creative AI OS.

FOTOhub.app developer console grows into a full creative infrastructure layer

FOTOhub's API console at fotohub.app/console has quietly turned into something closer to a small cloud provider than a settings page. Over the past weeks, the team behind FOTOhub Creative AI OS shipped real AWS S3 storage with enterprise controls, output routing that writes generations straight into a customer's own bucket, a webhook system with signed deliveries, and a much bigger documentation site to explain all of it. None of this replaces the generation tools people already know from the dashboard. It sits underneath them, for the developers, agencies, and product teams building on top of FOTOhub rather than clicking through it.

From a settings page to a console with nine tabs

The old idea of an API console was a page with a key and a copy button. What now lives at /console is organized into three groups: Developer API, Storage, and Compute Resources, each with its own set of tabs. Developer API alone covers a dashboard, key management, model access, tier limits, webhooks, usage analytics, job history, and request logs. Storage has its own pair of tabs for buckets and delivery destinations. Compute Resources exposes GPU instances, a hardware catalogue, and monitoring for anyone renting raw compute rather than calling a generation endpoint.

The dashboard itself is worth a mention because of what it does not do. It reads from a single aggregated endpoint that computes request counts, latency percentiles, spend, and per-model breakdowns from one pass over the data, so the numbers on screen always add up to the totals underneath them. A missing measurement shows as a blank, not a zero, because zero requests and zero milliseconds mean very different things and conflating them is how dashboards start lying to people.

API keys that do more than authenticate

Keys created in the console now carry structure that used to require a support ticket. Every key has a type, read-only, write, or admin, an optional IP allowlist, an optional referrer allowlist, a per-key rate limit, and its own output retention window. A key can point every generation it produces at a specific storage destination by default, and can carry a keepLocalCopy flag for teams that want the object in their own bucket without also paying to keep a duplicate in FOTOhub's storage once they trust the pipeline. Rotation is a single call, so a leaked key can be replaced without regenerating every downstream credential that depends on it.

Live keys start with fh_live_ and touch real credit balances and permanent storage. A second prefix, fh_test_, issues sandbox keys that return mock responses and store nothing beyond a 24 hour window, which is the difference between testing an integration against a staging account and just testing it safely, without a staging account at all.

Real AWS S3, not a wrapper around it

This is the part that changes what "storage" means on FOTOhub. Buying a bucket through the console provisions an actual AWS S3 bucket in one of sixteen regions across four continents, together with a dedicated IAM user scoped to that bucket alone. Nobody on the customer side ever sees or holds AWS credentials, and the console never asks for any. Provisioning is a short saga under the hood, bucket, encryption, a public access block, the IAM user, so a failure partway through rolls everything back and refunds the reservation rather than leaving someone the owner of half a working bucket.

What actually justifies calling this "enterprise grade" is the list of controls that are wired all the way through to the AWS API rather than stopping at the console UI. Lifecycle rules transition objects between storage classes and expire them on a schedule, with support for noncurrent version cleanup and an automatic cleanup rule for abandoned multipart uploads. CORS configuration, bucket policies, versioning, server side encryption with either AES256 or a customer supplied KMS key, and Object Lock in either a reversible governance mode or an immutable compliance mode are all real calls against real AWS resources, verifiable through get and put operations on the underlying configuration rather than through a settings toggle that nothing downstream reads.

Notifications are the honest way to describe what happens on upload. A bucket can be wired to publish S3 event notifications to an SNS topic, an SQS queue, a Lambda function, or EventBridge, filtered by prefix and suffix, whenever an object lands. What a customer's own Lambda does with that event is entirely up to them, which is a meaningfully different claim from "the platform runs AI on your uploads automatically," and a more useful one: it means a bucket can feed whatever pipeline someone already has, rather than only the one FOTOhub happened to build first.

A bucket can also carry a public hostname at label.s3point.fotohub.app, with individual folders published for anonymous reads while everything else in the same bucket stays private. Publishing is a property of the alias, not of individual objects, so revoking public access is one call that takes effect immediately across everything under that prefix, rather than a file by file cleanup.

Output routing: telling generations where to land

The feature that ties storage to the generation API is destinations and output rules, and it answers a question that used to require downloading a file and re-uploading it somewhere else. A destination points at either a console provisioned bucket or an external one, Cloudflare R2, Backblaze B2, MinIO, DigitalOcean Spaces, Wasabi, anything speaking the S3 protocol, verified at creation time with a real write, read, and delete against it. An output rule then matches a model id pattern against a destination and a path template, so a video call to seedance-2-0-mini can land at private/2026/08/{job_id}.mp4 in one bucket while an image call to a different model lands in a completely different folder, or a completely different provider, without either request needing to know the other exists.

```bash

curl -X POST "https://apis.fotohub.app/v1/auth/keys/$KEY_ID/output-rules" \

-H "Authorization: Bearer $FH_JWT" \

-H "Content-Type: application/json" \

-d '{

"modelPattern": "seedance-2-0-*",

"destinationId": "c47b8e91-2d5f-4a06-8b3c-1e9f7d602a58",

"pathTemplate": "private/{YYYY}/{MM}/{job_id}.{ext}",

"priority": 10

}'

```

The response to a generation call still returns the same signed FOTOhub URL it always has, so nothing already built against the API breaks. What is new is a delivery block naming the exact key the object will land at, before the transfer to the external bucket even finishes, because the key layout is deterministic and computable ahead of time. That is deliberately the thing to poll for a head request on your own bucket rather than the API response itself, since delivery is detached from the generation call by design: a slow or briefly unreachable bucket never blocks or fails the generation it is receiving.

Webhooks, signed and accounted for

The webhook system covers the async side of the same problem: knowing when something finished without polling for it. Events cover generation completion and failure, low and depleted credit balances, batch job completion, and a family of background removal and commerce pipeline events. Every delivery carries an HMAC-SHA256 signature in an X-FotoHub-Signature header, computed over the raw request body, which is the detail that actually matters: verifying against a re-serialized copy of the JSON produces a different signature and a false rejection, so the implementation has to reach for the raw bytes before anything touches them.

```python

import hmac

import hashlib

def verify_signature(payload_bytes: bytes, signature: str, secret: str) -> bool:

expected = hmac.new(secret.encode("utf-8"), payload_bytes, hashlib.sha256).hexdigest()

return hmac.compare_digest(expected, signature)

```

A failed delivery gets three attempts with a short exponential backoff and is then logged and dropped, not silently disabled and not endlessly retried, and delivery logs are available through the console for anyone who needs to see exactly what their endpoint returned and when.

The documentation to go with it

Explaining a surface this wide needed a real documentation site rather than a page of curl examples, so docs.fotohub.app grew alongside the console itself. The API reference alone now runs to dozens of pages across generation, video, advanced processing, and platform topics, storage and webhooks and rate limits among them, with a separate guides section walking through end to end setups like routing generations into a customer's own bucket, CLI installation, and webhook handling in more depth than an endpoint list allows. Every code sample on the storage and webhook pages exists in Python, TypeScript, Go, and raw curl side by side, because a developer evaluating an integration wants to read it in the language they are about to write it in, not translate it themselves.

The official SDKs, fotohub on PyPI and fotohub on npm, both ship the webhook management methods, list, create, update, delete, test, and log retrieval, under matching names in each language. Storage is the honest gap to flag rather than gloss over: the S3 API is deep enough that the SDKs have not wrapped all of it yet, so building against the newest bucket and destination endpoints today means calling the REST API directly rather than through a client method, which the documentation says plainly rather than implying a coverage that is not there yet.

Why this matters beyond the feature list

None of this is a new product bolted onto FOTOhub. It is the same Creative AI OS, image, video, audio, text, and 3D generation across more than two hundred models from ten or more providers, gaining the plumbing that turns "call an API and get a file back" into "call an API and have the result land exactly where an existing system expects it, with a signal the moment it is done." A marketing team generating product video at volume can now have every render write straight into the bucket their CMS already reads from. An agency running client work across separate S3 buckets can route by model without touching a line of pipeline code for each new client. A platform integrating FOTOhub's generation into its own product can subscribe to webhooks instead of polling, and verify every delivery against a signature instead of trusting an open endpoint.

FOTOhub has raised 8.6 million dollars across five rounds in 2026, reaching a 180 million dollar valuation with Amazon Web Services among its investors, and serves more than 750,000 users across more than 40 countries. The console work described here is a direct product of that AWS relationship: the storage layer runs on real AWS infrastructure, provisioned and managed through FOTOhub's own control plane rather than through a thin proxy in front of someone else's dashboard. It is also a bet that the next stage of growth for a Creative AI platform runs through the teams building products with it, not only the people generating inside it directly, and that a platform serious about that audience needs infrastructure that reads like infrastructure, not like a feature flag.

About FOTOhub. FOTOhub is a creative AI platform combining a multi-provider model catalogue across image, video, audio, text, and three-dimensional generation with a brand system, a workflow engine, and a documented API, exposed through official SDKs, real AWS S3 storage, and a signed webhook layer.

Press contact. FOTOhub Press Team, FOTOhub.app

Learn more: Developer console · API documentation · Investor relations · Crunchbase