Create a creator account (sign-up from your page)
API reference

Create a creator account (sign-up from your page)

Creates a creator (or agency) account from your own sign-up page and returns the ID-check link to redirect the creator to.

View as MarkdownUpdated Oct 17, 2026
POST/api/external/accountsNew

Creates a creator (or agency) account from your own sign-up page and returns the ID-check link to redirect the creator to.

The account is created with everything our own onboarding sets — handle, display name, bio, residency, avatar, banner and subscription price — and starts as pending_kyc. Send the creator to kycUrl (a full-page redirect or a new tab, never an iframe). When they finish, they come back to your kycReturnUrl with ?kyc=approved|declined|in_review. That parameter is only a hint for your UI: the decision arrives as the account.kyc_updated webhook, and selling is unlocked only once the account is active.

The response also holds an apiKey for the new account, bound to your app. Use it straight away to upload media and create drops for the creator. Store it like a password; it is shown once.

Referral commission. Accounts you create are attributed to your app owner’s account, which earns the standard referral commission on their sales.

Terms. Show the creator our Terms of Service, Privacy Policy and 2257 statement and record their acceptance. Send legalAccepted: true with the IP address and user agent of the creator’s browser at the moment they accepted (not your server’s). We generate the signed acceptance record from them.

Owner-held key + enablement

Call this with a key your app owner holds: their own, or one their agency minted for its personas or managed creators. Creator sign-up has to be enabled for your app; ask us to enable it.

Authentication

Send the creator's API key as a bearer token: Authorization: Bearer dpfn_…. See Authentication & API keys.

Request body

Content type: application/json

NameTypeRequiredDescription
emailstringRequiredThe creator’s email. It becomes their sign-in. 409 if it is already registered.
Format: email
passwordstringOptionalOptional. Leave it out and we email the creator a link to set one (valid 7 days). Either way they get a welcome email.
Min length: 8
Max length: 200
usernamestringRequiredPublic @handle (letters, digits, underscores). 409 when taken.
displayNamestringOptionalDisplay name on the profile.
Max length: 50
biostringOptionalProfile bio.
Max length: 500
locationstringOptionalOptional profile location line.
Max length: 100
accountTypestringOptionalagency is for AI-creator operators that run several personas.
One of: creator, agency
Default: "creator"
residencyCountrystringRequiredCountry of residence, ISO 3166-1 alpha-2. Used for payouts and tax.
Pattern: ^[A-Z]{2}$
avatarUrlstringOptionalhttps URL of the profile picture (JPEG, PNG or WebP, ≤4 MB). Fetched once, stripped of metadata and moderated like a normal upload. A bad image never fails the sign-up; check images.avatar.
Format: uri
bannerUrlstringOptionalhttps URL of the profile banner. Same rules as avatarUrl.
Format: uri
subscriptionobjectOptionalOptional subscription offer for the profile.
Show child attributes
priceUsdnumberPrice in USD dollars, $5–$750.
Min: 5
Max: 750
intervalstringBilling period.
One of: monthly, weekly
Default: "monthly"
trialDaysintegerFree trial length.
Default: 0
Min: 0
Max: 30
legalAcceptedbooleanRequiredMust be true: the creator accepted the Terms of Service, Privacy Policy and 2257 statement on your page.
acceptedFromIpstringRequiredThe creator’s browser IP at acceptance.
acceptedUserAgentstringRequiredThe creator’s browser user agent at acceptance.
Max length: 500
kycReturnUrlstringOptionalhttps URL the creator returns to after the ID check. We append ?kyc=<status>.
Format: uri
A creator with profile and subscription
{
  "email": "[email protected]",
  "username": "valeria",
  "displayName": "Valeria",
  "bio": "New sets every Friday.",
  "residencyCountry": "SE",
  "avatarUrl": "https://cdn.example.com/valeria/avatar.jpg",
  "bannerUrl": "https://cdn.example.com/valeria/banner.jpg",
  "subscription": {
    "priceUsd": 9.99,
    "interval": "monthly",
    "trialDays": 0
  },
  "legalAccepted": true,
  "acceptedFromIp": "203.0.113.7",
  "acceptedUserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) …",
  "kycReturnUrl": "https://crm.example.com/onboarding/done"
}

Responses

201Created. Redirect the creator to `kycUrl`; keep `accountId` and `apiKey`.
NameTypeDescription
accountIdstringThe new account’s id.
usernamestringPublic @handle (without @).
displayNamestring | nullDisplay name.
emailstring | nullSign-in email.
Format: email
accountTypestringWhat the account was created as.
One of: creator, agency
statusstringpending_kyc until the ID check is approved, then active (can sell and get paid).
One of: pending_kyc, active
sellerStatusstringInternal seller state, for support (PENDING_KYC, KYC_IN_REVIEW, KYC_REJECTED, VERIFIED_CREATOR, VERIFIED_AGENCY).
kycStatusstringID-check state. session_created = link opened, not finished; processing = approved, compliance documents still being generated.
One of: not_started, session_created, in_review, processing, approved, rejected
profileUrlstringPublic profile URL.
Format: uri
createdAtstringWhen the account was created.
Format: date-time
apiKeystringA key for the new account, bound to your app. Shown once.
kycUrlstring | nullThe ID-check link. Null if it could not be opened right now; then call create-kyc-session.
Format: uri
kycExpiresAtstring | nullThe link is reused until then; ask for a new one after.
Format: date-time
referralCreditedbooleanTrue when the account was attributed to your app owner for referral commission.
imagesobjectWhat happened to avatarUrl / bannerUrl: "saved", "failed" or null (not sent).
Show child attributes
avatarstring | nullAvatar result.
One of: saved, failed
bannerstring | nullBanner result.
One of: saved, failed
Example response
{
  "accountId": "clxac0001acct",
  "username": "valeria",
  "displayName": "Valeria",
  "email": "[email protected]",
  "accountType": "creator",
  "status": "pending_kyc",
  "sellerStatus": "PENDING_KYC",
  "kycStatus": "session_created",
  "profileUrl": "https://www.dropfans.io/u/valeria",
  "createdAt": "2026-10-17T16:00:00.000Z",
  "apiKey": "dpfn_3f9c…",
  "kycUrl": "https://verify.didit.me/session/…",
  "kycExpiresAt": "2026-10-18T16:00:00.000Z",
  "referralCredited": true,
  "images": {
    "avatar": "saved",
    "banner": "saved"
  }
}

Errors

StatusBodyWhen
400{"error":"residencyCountry must be an ISO 3166-1 alpha-2 code (e.g. \"SE\").","code":"invalid_input","field":"residencyCountry"}A field failed validation. `field` names it.
409{"error":"There is already a DropFans account with this email. Sign in instead.","code":"email_taken"}The email is registered.
409{"error":"That profile link is taken. Pick another.","code":"username_taken"}The handle is taken.
401{"error":"Unauthorized","code":"unauthorized"}Missing or invalid API key.
403{"error":"This endpoint needs a key bound to an approved app.","code":"app_key_required"}A Personal key was used.
403{"error":"Use the app owner's key for this endpoint.","code":"owner_key_required"}The key was minted by a creator for themselves. App-level calls need a key held by your app owner: their own, or one their agency minted for its personas or managed creators.
403{"error":"This app is not enabled for this endpoint. Contact support.","code":"capability_missing"}Creator sign-up has not been enabled for your app yet.
429{"error":"At most 20 sign-ups per hour.","code":"rate_limited"}Too many sign-ups from your app this hour. `Retry-After` says when to retry.

Rate limiting

Every response carries the X-RateLimit-Tier header and, on limited tiers, the per-minute and per-day trios — read X-RateLimit-Remaining and X-RateLimit-Reset instead of hardcoding limits. Details in Rate limits.

Code samples

curl -X POST "https://www.dropfans.io/api/external/accounts" \
  -H "Authorization: Bearer $DROPFANS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "[email protected]",
  "username": "valeria",
  "displayName": "Valeria",
  "bio": "New sets every Friday.",
  "residencyCountry": "SE",
  "avatarUrl": "https://cdn.example.com/valeria/avatar.jpg",
  "bannerUrl": "https://cdn.example.com/valeria/banner.jpg",
  "subscription": {
    "priceUsd": 9.99,
    "interval": "monthly",
    "trialDays": 0
  },
  "legalAccepted": true,
  "acceptedFromIp": "203.0.113.7",
  "acceptedUserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) …",
  "kycReturnUrl": "https://crm.example.com/onboarding/done"
}'

Questions? [email protected]