Promotions

Create Promotion

Creates a new promotion (discount offer or free trial) on the creator's profile. Promotions can target new subscribers, expired subscribers, or both (new_and_expired creates two OF-side promotions in one call). For free-trial links specifically, prefer the /v1/{account_id}/trial-links endpoints — this is the lower-level OF-native primitive. Requires permission api_promotions_create.

https://public-api.fansmetric.com
POST/v1/{account_id}/promotions
Bearer

Authorization

default
AuthorizationBearer <token>

Send your FansMetric API key as a Bearer token in the Authorization header.

In: header

Path Parameters

  • account_id*integer

    OnlyFans numeric account ID.

Request Body

application/json
  • type*string

    Audience. One of new, expired, new_and_expired. new_and_expired creates two OF promotions in a single call.

  • discount*string

    Discount percentage applied to the subscription. Range 1–100. Set to 100 to turn the promotion into a Free Trial — freeTrialDays then becomes required.

  • subscribeCounts*string

    Limit on how many subscribers can claim. Set to 0 for unlimited. Max: 100.

  • subscribeDays*string

    Days the discount remains in effect for a redeeming subscriber. Range 1–30.

  • finishDays*string

    Days before the promotion expires. Range 0–30. 0 means open-ended.

  • messagestring

    Optional message shown to subscribers (max 500 chars).

  • freeTrialDaysstring

    Required when discount == 100. Length of the free trial in days. Range 1–30.

Response Fields

  • data[]array

    Created promotions. Length 1 for new/expired, length 2 for new_and_expired.

  • data[].idinteger

    OnlyFans promotion ID. Pass to Finish Promotion to stop it early.

  • data[].typestring

    new or expired (the per-row audience, not the request type).

  • data[].canClaimboolean

    Whether the promo is currently claimable by eligible fans.

  • data[].claimsCountinteger

    Number of subscribers who have already redeemed.

  • data[].createdAtstring

    ISO timestamp when the promo was created.

  • data[].finishedAtstring

    ISO timestamp when the promo expires (createdAt + finishDays).

  • data[].isFinishedboolean

    true once the promo has expired or been finished early.

  • dataobject | array

    Endpoint-specific payload. See the fields below for this route.

  • _meta._credits.usedinteger

    Credits consumed by this request (currently always 1).

  • _meta._rate_limits.limit_minuteinteger

    Maximum requests per minute for the organization.

  • _meta._rate_limits.remaining_minuteinteger

    Remaining requests in the current minute window.

  • _meta._rate_limits.limit_dayinteger

    Maximum requests per day for the organization.

  • _meta._rate_limits.remaining_dayinteger

    Remaining requests in the current day window.

curl --request POST "https://public-api.fansmetric.com/v1/100000001/promotions" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "type": "new",
  "discount": 50,
  "subscribeCounts": 100,
  "subscribeDays": 30,
  "finishDays": 7,
  "message": "Half off your first month! 🎉"
}'

Response

200
{
"data":[
0:{
"id":123
"message":"Half off your first month!"
"rawMessage":"Half off your first month!"
"hasRelatedPromo":false
"price":0
"type":"new"
"canClaim":true
"claimsCount":0
"subscribeCounts":100
"subscribeDays":30
"createdAt":"2026-06-01T12:00:00+00:00"
"finishedAt":"2026-06-08T12:00:00+00:00"
"isFinished":false
}
]
"_meta":{
"_credits":{
"used":1
}
"_rate_limits":{
"limit_minute":1000
"remaining_minute":999
"limit_day":50000
"remaining_day":49999
}
}
}