Users
Authenticated creator profile, payout data, device tokens, and creator-level default compliance flags.
GET /api/user
Return the authenticated user's current profile.
- Auth required: Yes
- Roles: Authenticated creator
Success response example
{
"success": true,
"errors_message": null,
"data": {
"id": 7,
"type": "business",
"email": "creator@example.com",
"first_name": "Alyssa",
"last_name": "Creator",
"birth_date": "1998-05-12",
"stripe_url": null,
"fee": {
"percentage": 3
},
"bank_data": {
"iban": "LU150103994632856918",
"bic_swift": "UNCRIT2B912"
},
"address": "1 Main Street",
"is_verified": true,
"veriff_first_name": "Alyssa",
"veriff_last_name": "Creator",
"veriff_is_matched": true,
"is_adult_content": true,
"is_verif_age": false,
"is_epoch_enabled": true,
"currency_id": 1
}
}Returned fields
| Field | Type | Notes |
|---|---|---|
id | integer | User id. |
type | string | Legacy/internal account type. Do not build feature logic on this field alone. |
email | string | Creator email. |
first_name | string | Creator first name. |
last_name | string | Creator last name. |
birth_date | string | YYYY-MM-DD. |
stripe_url | string or null | Legacy / conditional onboarding link. |
fee | object | Current creator fee resource. |
iban | string or omitted | Convenience exposure when IBAN exists in bank data. |
bic_swift | string or omitted | Convenience exposure when BIC/SWIFT exists in bank data. |
bank_data | object or null | Current payout fields. |
country_code | string or null | The creator's country of residence, ISO 3166-1 alpha-2 (since 2026-10-08); null until set. |
payout_method | string | wire or crypto (since 2026-10-08): which saved details the next payout uses. Both sets stay stored. Omitted where bank_data is. |
tron_usdt_wallet | string or null | TRON (TRC-20) USDT address for crypto payouts, or null. Omitted where bank_data is. |
vat_number | string or null | The creator's VAT number (since 2026-10-08). Set through PATCH /api/user, stored only once the EU VAT register (VIES) confirms it. Omitted where bank_data is. |
payout_recipient | object or omitted | Who a payout is made out to - never a name the creator types in (since 2026-09-27): name and basis (company: the company's legal name from the creator's company record; verified_person: the name on the ID Veriff verified; account_name: the account's own name, shown until the identity is verified). The bank details may change, the recipient may not. Omitted in an agency session and for the Telegram Mini App, like bank_data. |
address | string or null | Optional creator address. |
is_verified | boolean | Creator identity verification result. |
veriff_first_name | string or null | Verified first name snapshot. |
veriff_last_name | string or null | Verified last name snapshot. |
veriff_is_matched | boolean or null | Name-match status from verification flow. |
is_adult_content | boolean | Default AVS flag for new uploads. |
is_verif_age | boolean | Default buyer age-check requirement for new uploads. |
upload_defaults | object or null | Account-level upload presets (see below). |
is_epoch_enabled | boolean | Current payment-provider enablement state. |
currency_id | integer | Creator currency id. |
upload_defaults object
Optional JSON stored on the user. Used as defaults for bulk uploads and product creation:
| Field | Type | Description |
|---|---|---|
is_adult_content | boolean | Default AVS flag |
is_downloadable | boolean | Default download setting |
is_verif_age | boolean | Default age verification |
default_price | integer | Suggested price in cents (e.g. 500 = $5.00) |
folder_id | integer | Default content folder |
PATCH /api/user/
Update user profile fields and payout fields.
- Auth required: Yes
- Roles: Authenticated creator
- Content type:
application/json
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
first_name | string | Yes | Max 255 chars. |
last_name | string | Yes | Max 255 chars. |
iban | string | No | Legacy convenience field. |
bic_swift | string | No | Legacy convenience field. |
bank_data | object | No | Flexible payout fields by currency. |
country_code | string | No | Country of residence, ISO 3166-1 alpha-2; an unknown code answers 422. |
payout_method | string | No | wire or crypto: which saved details a payout uses. Switching does not delete the other set. |
tron_usdt_wallet | string or null | No | TRON (TRC-20) USDT address (T + 33 characters); null removes it. Another format answers 422. |
vat_number | string or null | No | VAT number with the country prefix (DE123456789). Checked against VIES first: an invalid or unknown number answers 422 and nothing is stored; null removes it. |
upload_defaults | object | No | Account-level upload presets (see upload_defaults schema above). |
Success response example
{
"success": true,
"errors_message": null,
"data": {
"user": {
"id": 7,
"first_name": "Alyssa",
"last_name": "Creator",
"bank_data": {
"iban": "LU150103994632856918",
"bic_swift": "UNCRIT2B912"
}
}
}
}Important notes
- The route is parameterized as
/api/user/{user}.{user}must be the id of the authenticated account (theidfromGET /api/user); any other id answers403witherrors_code: "forbidden". - This endpoint does not update creator default flags. Use
/api/user/profile/has-adultfor that - of its two defaults onlyis_verif_agestill matters: every product is AVS+, whatever the account'sis_adult_contentsays.
GET /api/user/payment-options
Read the account-wide payment options for customers: which checkout tiles a buyer sees, whether the Send a tip button is offered on the product pages, and the smallest tip. Every product follows these values until it carries its own — see Payment options.
- Auth required: Yes
- Roles: Authenticated creator, login token only. A generated API key answers
403witherrors_code: "forbidden"(Account settings are not available for generated API keys.); a generated key sets the options per product instead. An agency account is refused with403as well.
Success response example
{
"success": true,
"errors_message": null,
"data": {
"tiles": { "paypal": true, "card": true, "crypto": false },
"tips_enabled": true,
"min_tip_cents": 500,
"min_tip_override_cents": 500,
"tip_limits": { "min_cents": 500, "max_cents": 30000 }
}
}Returned fields
| Field | Type | Notes |
|---|---|---|
tiles | object | true = the tile is shown at the checkout. Keys: paypal, card (the tile "Credit Card / Other") and crypto. See what a buyer sees. |
tips_enabled | boolean | The tip button on the product pages. The creator's own tip page and the tip card in Telegram are not affected. |
min_tip_cents | integer | The smallest tip in effect, minor units. |
min_tip_override_cents | integer or null | The creator's own value; null = the platform minimum. |
tip_limits | object | The platform range in minor units: min_cents, max_cents. |
PATCH /api/user/payment-options
Change those account-wide values. They apply to every product that does not carry its own value, existing products included.
- Auth required: Yes
- Roles: Authenticated creator, login token only (same
403as above) - Content type:
application/json
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
tiles | object | No | Any subset of paypal, card, crypto. A key that is left out keeps its current value. |
tips_enabled | boolean | No | The tip button on the product pages. |
min_tip_cents | integer or null | No | Minor units, within tip_limits and a whole amount (a multiple of 100). null = back to the platform minimum. |
Success response example
The response body is the same as for GET /api/user/payment-options.
{
"success": true,
"errors_message": null,
"data": {
"tiles": { "paypal": true, "card": true, "crypto": false },
"tips_enabled": false,
"min_tip_cents": 100,
"min_tip_override_cents": null,
"tip_limits": { "min_cents": 500, "max_cents": 30000 }
}
}Important notes
- Hiding a tile only hides the tile. The payment method itself stays switched on, and a buyer can still end up using it through the provider's own page.
- At least one tile has to stay shown. Hiding all three answers
422witherrors_code: "validation_failed"and the messageAt least one payment option has to stay visible. - If none of the shown tiles is available for a product, the checkout shows all available ones, so a product always stays buyable. The fallback offered after a declined card payment is always shown.
- A product that carries its own
payment_optionskeeps them and no longer follows the account.
PATCH /api/user/profile/has-adult
Update creator-level default compliance toggles for new uploads and optionally cascade them to existing products.
- Auth required: Yes
- Roles: Authenticated creator
- Content type:
application/json
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
is_adult_content | boolean | Yes | Still required by the call, without effect on products: every product is AVS+. |
is_verif_age | boolean | Yes | Default age-check flag. |
is_update_products | boolean | No | If true, backend also updates existing products for enabled flags. |
Success response example
{
"success": true,
"errors_message": null,
"data": {
"id": 7,
"is_adult_content": true,
"is_verif_age": true
}
}Side effects
- updates user defaults immediately
- if
is_update_products=trueand a flag istrue, backend updates existing products for that flag as well
POST /api/user/fcm
Store an FCM token for push notifications.
- Auth required: Yes
- Roles: Authenticated creator
Request body
| Field | Type | Required |
|---|---|---|
token | string | Yes |
Success response example
{
"success": true,
"errors_message": null,
"data": "Token stored"
}DELETE /api/user/fcm
Delete an FCM token.
- Auth required: Yes
- Roles: Authenticated creator
Request body
| Field | Type | Required |
|---|---|---|
token | string | Yes |
Success response example
{
"success": true,
"errors_message": null,
"data": "Token removed"
}DELETE /api/user
Delete the authenticated creator account.
- Auth required: Yes
- Roles: Authenticated creator
Success response example
{
"success": true,
"errors_message": null,
"data": "Deleted"
}Side effects
- deletes all current auth tokens
- soft-deletes the user
- dispatches
UserDeleteJob
AI models of a creator
Since 2026-10-12 a creator opens AI models of its own, the way an agency does. An AI model is an account of kind ai_model that belongs to the creator: its own library, vault, products, sales links and statistics, no login of its own. It sells fully AI-generated content only - a file declared as anything but synthetic is refused (422, see AI content). It is never verified itself: the creator behind it is the responsible seller, so the model takes uploads and sells while the creator's identity verification is complete and the creator account is not blocked. Everything it earns is booked to the creator's wallet, in the creator's currency, and counts as the creator's sale - on the creator's transaction report, in the creator's referrer's commission, and in the webhooks the creator registered (see below). Nothing is shared with an agency the creator is connected to.
| Method | Path | Purpose |
|---|---|---|
GET | /api/user/ai-models | Your AI models, each with its account_key; can_create, blocked_reason, limit |
POST | /api/user/ai-models | Create one: { "name": "Luna Vale" } (2 to 80 characters) |
PATCH | /api/user/ai-models/{model} | Rename |
DELETE | /api/user/ai-models/{model} | Deactivate - final: its pages go offline for good, the sales history and refunds stay |
POST | /api/user/ai-models/{model}/session | The session the dashboard works in the model with (login token only) |
Login token, or an API key with can_manage_ai_models (API keys). The model is addressed by its own id - there is no relationship. A creator runs up to limit active models at the same time (422 beyond it); deactivated ones do not count. The name is the model's stage name and is free; the profile address is ten random lower-case letters and digits, given once and never changed by a rename.
Working in a model with a key. The model's account_key has the form aim_<id>. Send it as the X-Fangate-Account header on any call your key may make - upload, vault, products, webhooks - and the call runs as the model, within the key's own permissions, exactly as an agency works in its accounts. A bare id is refused (422 agency_account_key_invalid); a deactivated model, or a model that is not yours, answers 404 agency_account_not_found. Inside a model the account's own matters stay closed: no payout, no bank details, no password, no account deletion (403).
Webhooks. The webhooks of the creator's own account hear the model's events as well (a sale, a refund, a product that became sellable, a file verdict). Such a delivery carries an account block naming the model: { "account_key": "aim_90211", "kind": "ai_model", "name": "Luna Vale" }. Webhooks an agency registered on the creator's account do not hear the creator's models.
Why a model cannot upload. 422 ai_model_owner_verification_required (requires_verification: false): the creator behind the model is not verified, or the model is deactivated. The creator verifies in the creator's own account, never in the model.
Payout account
Fangate stores the payout account in bank_data. Since 2026-09-27 the account type is the creator's choice whatever currency the account earns in (GET /api/app-data → bank_account_types[]); the fields decide the type:
| Type | Keys |
|---|---|
| IBAN / BIC | iban, bic_swift |
| US routing number | routing_number, account_number |
| UK sort code | sort_code, account_number |
One account receives every payout, whatever currency it was earned in; the payout currency decides the rail and its fee (withdrawal_fees[], see App data). The payout is made out to payout_recipient (see GET /api/user), not to a name in bank_data. The account is optional on Fangate's own registration (a collapsed tile on the currency step); a creator without one sees a reminder and POST /api/wallet/cashout answers 422 with payout_account_required.
Crypto payouts (since 2026-10-08). Available once Fangate has switched them on: GET /api/app-data carries crypto_payouts_enabled; while it is false, payout_method: crypto answers 422 validation_failed (errors_field: payout_method) and the tile is shown as "coming soon". payout_method decides which saved details a payout uses: wire pays to bank_data, crypto pays USDT to tron_usdt_wallet (a TRON TRC-20 address, T + 33 characters). Both sets stay stored; switching the method does not delete anything. With crypto and no wallet the cashout answers 422 payout_account_required as well. The crypto rail has a withdrawal fee of its own (withdrawal_fees[] in App data). The USDT amount sent is the payout minus the withdrawal fee and any bank conversion fee, at the rate of the day; the payout confirmation names the USDT amount that was actually sent and the wallet it went to.