Skip to content

Vault for integrations ​

The vault is the creator's media library: every file the creator has, whether it is part of a product or not. This guide walks a CRM or automation through the whole cycle with a generated API key - list and filter, upload, classify, declare consent, wait for moderation, build products from vault files, and take products apart again - so the creator does not have to open the Fangate dashboard for day-to-day work.

Prerequisites: a generated API key with Manage content (see API Keys). Read-only keys can do the reads on this page, nothing else.


1. List and filter ​

GET /api/media - paginated, newest first by default. Rate limit: 60 requests per minute per key and IP, plus 120 per minute per IP across all keys behind it (shared with GET /api/media/{media}). An agency's key working inside its accounts has a higher ceiling per IP - see Rate limits.

ParameterTypeMeaning
page, limitintegerPagination (limit up to 100).
status[]pending, approved, rejectedModeration state. Scalars work too (status=approved).
media_type[]image, videoKind of file.
consent[]required, pending, providedConsent bucket: required = the owner has to act (nobody tagged yet, or declined, or rescinded); pending = requested, no answer yet; provided = nothing to clear (not_required) or consent given. Read consent.status per file for the exact state.
folder_idintegerVault folder (folders with scope=vault, see Content Folders).
unlinkedbooleanOnly files that belong to no product.
livebooleanApproved by moderation and consent cleared - the files a product can be built from.
standard_only / ai_onlybooleanOnly non-AI files / only AI files.
sortnewest, oldest
searchstringTitle search, up to 120 characters.

The response is a page: data[], total, per_page, current_page, pages_total. Each file carries status, ai_origin, ai_label, is_should_consent, consent { status, required, fulfilled }, product_ids, is_linked, thumbnail, preview, preview_blurred. source (the full-size file) is only returned by GET /api/media/{media}.

live=1 is necessary, not sufficient, for a sale: a product built from live files can still be blocked by a pending manual review, an open price review or a switched-off AI domain. Always read is_accessible and purchase_block_code on the product.


2. Upload into the vault ​

  1. POST /api/upload-sessions - session_type: device_multipart, file_name, file_size_bytes, mime_type, and the AI answer ai_origin (+ ai_attested for AI values). See AI content for the four values.
  2. Upload the bytes as instructed (initial_upload for single-part, POST /api/upload-sessions/{id}/parts for multipart), then POST /api/upload-sessions/{id}/complete. From your server this works without further setup; a browser on your own domain needs its origin on the storage allow-list first - see Uploading from your server or from a browser.
  3. Poll GET /api/upload-sessions/{id} until status is ready. Presigned URLs are valid for 15 minutes, a session for 24 hours.
  4. POST /api/media with upload_session_id, optional title, description, folder_id, is_should_consent, and ai_origin / ai_attested if you did not send them on the session.

Several files at once: POST /api/media/bulk opens up to 50 sessions with shared defaults (including defaults.ai_origin and defaults.ai_attested); then run steps 2-4 per session.

The AI answer is mandatory for keys created since the AI release and for all content keys after the announced cut-over: without it, step 4 is refused with 422 and errors_code: ai_origin_required. The session stays ready - repeat the call with the value within the session's 24 hours; an asset that is never attached is cleaned up after 7 days.


A file that shows another person needs that person's consent before it can be sold. Declare it on the file, not on the product:

  • Tag registered creators: POST /api/media/{media}/consent-tags with date (the consent date) and tagged_creator_ids[] (or a single tagged_creator_id). Find ids with GET /api/creators/search?q=.
  • Tag or invite by email: same call with email. A registered address is tagged directly; an unknown address needs tag_invite: true (and an optional message) - Fangate emails an invitation and the file waits for their answer. An unknown address without tag_invite is refused with 400. The call answers 200 with an empty data; read the state back with GET.
  • Mark now, tag later: PATCH /api/media/{media} with is_should_consent: true blocks the file until a person is tagged and has accepted.
  • Read the state: GET /api/media/{media}/consent-tags, or the consent object on every listing.

consent.status is one of not_required, review_open, consent_requested, consent_provided, declined, consent_rescinded; the list filter consent[] groups them into required (review_open, declined, consent_rescinded - the owner has to act), pending (consent_requested) and provided (not_required and consent_provided).

An AI file of another person (ai_origin: real_person_other) is marked as needing consent automatically.


4. Wait for moderation ​

Moderation runs after step 4 and takes seconds to minutes (videos longer; a first upload of a high-risk account waits for a manual review). For the product, a webhook tells you: product.sellable is sent once when the product can be bought (moderation, consent and, above the threshold, price approval are through), product.blocked when it cannot be sold, with the reason. There is no event per file: to follow single vault files before you build a product, poll the list (GET /api/media?status[]=pending) with a backoff of at least 30 seconds rather than polling every file; the list and the single-file endpoint share a limit of 60 requests per minute per key. Payment events (payment.successful, payment.failed, payment.pending, payment.cancelled) are described on the same page.


5. Build a product from vault files ​

POST /api/products with

FieldNotes
media_ids[]Vault files of the creator. Mixing AI and non-AI files makes the product an AI product (see AI content). A file with ai_classified: false (not classified yet, reported as none) counts as non-AI until it is classified; the product flag follows then.
priceCents, at least 500.
titleOptional.
is_downloadableSend it explicitly. Absent means false on this call.
is_adult_contentIgnored - every product is AVS+ and answers true.
is_verif_ageDefault from the account's upload defaults.
per_media_consent, media_consents[], consent_dateDeclare consent for specific files in the same call: "per_media_consent": true, "consent_date": "2026-09-12", "media_consents": [{ "media_id": 101, "tagged_creator_ids": [55] }]. Without per_media_consent: true the media_consents list is silently ignored.

No ai_origin here: the files are classified already. The response is the full product resource (201), with link, is_accessible and purchase_block_code.

Add or remove files later with POST /api/products/{product}/media (media_ids[], optionally with the consent fields above) and DELETE /api/products/{product}/media/{media}. Removing the last file deletes the product; in that case data is the string "deleted" instead of the product object.


6. Take a product apart ​

DELETE /api/products/{product} removes the product. With an API key its files stay in the vault unless you ask for them to go - send delete_media=1, and they are deleted as long as no other product uses them:

DELETE /api/products/123?delete_media=1

DELETE /api/media/{media} deletes a vault file; products that only had this file are deleted with it, other products lose the file.


7. Is it sellable? ​

Read GET /api/products/{product}:

is_accessiblepurchase_block_codeMeaning
truenullBuyers can purchase.
falsemoderation_not_approvedNo file of the product is approved yet. One approved file is enough for the sale; a rejected file next to it does not block - check status per file in GET /api/media if every file must be through.
falsemanual_review_pendingWaiting for a manual review (high-risk accounts).
falseconsent_recipient_missing, consent_pending, consent_declined, consent_rescindedConsent workflow open or negative.
falseprice_review_pendingThe price is above the threshold and awaits approval by Fangate.
falsemedia_unavailableA file is not available in storage.
falseai_rail_unavailableAI product while Fangate's platform-wide AI switch is off.

8. Running many accounts from your own servers ​

A vault or CRM that every client connects with their own API key runs all of those keys from a few fixed servers. Two things can be arranged for that by mail to info@fangate.app:

  • Registered server addresses. The ceilings per IP are meant for one caller's address; behind your server every connected creator's key shares them. Send us the egress addresses of your servers (single IPs or CIDR ranges) and calls with a generated key from there are counted on a ceiling of their own - see Rate limits. The limit per key and account stays.
  • Fangate in a window inside your product. What a creator does in person - changing payout details or the password, managing keys - happens in the Fangate dashboard (signing up and identity verification can also run from screens of your own). Opening it in a pop-up window from your product needs nothing from us; the creator signs in there once per browser. Showing it inside a frame of your page is possible in individual cases only, after you have registered the page's domain with us, and is not something we promise for every integration: browsers restrict what a page inside a foreign frame may store, so the sign-in may not persist.

Fangate backend developer documentation