Create a source-link rule
Author a durable rule mapping an OnlyFans link identity to a source, so future fans auto-attribute without manual confirmation.
A source_link row is a standing rule: bind one OnlyFans link identity to one real domain-source
you've registered. Confirming a scanned campaign (see
Confirm the source for a scanned campaign)
writes one of these for you automatically — this page is for authoring one directly, typically a
broader pattern that should catch links you haven't scanned yet.
Create a rule
curl -X POST "https://app.tease.link/api/admin/source-links" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"match_type": "name_prefix",
"match_value": "insta_",
"domain_source": "ig-main.link",
"channel": "instagram"
}'match_type is one of four, checked in this order of what they mean (not priority — see below):
match_type | Matches when |
|---|---|
provider_id | The link's vendor id equals match_value exactly. |
exact_name | The link's name equals match_value exactly. |
name_prefix | The link's name starts with match_value. |
regex | match_value matches anywhere in the name (re.search, case-insensitive). |
domain_source must be a real registered domain — the endpoint 404s on an unknown host and
400s if you try to target __organic__ or __pending__; those sentinels are reserved for
"no link at all" and "not mapped yet," never an owner-chosen destination.
A regex is validated at write time, not just at match time
A pathological pattern (nested quantifiers like (a+)+, or an alternation under a quantifier
like (a|aa)+) can hang the attribution worker with no timeout available in stdlib re. The
create endpoint rejects those shapes outright, caps the pattern at 200 characters, and limits
it to 12 groups / 24 quantifiers. If your pattern is refused, fall back to exact_name or
name_prefix — real OF link names rarely need more.
Evaluation order
When a link matches more than one active rule, rows are scanned in ascending priority, then
by row id, and the first match wins. priority defaults to 100 for every rule created
through this endpoint — the API doesn't currently expose a way to set it — so among your own
manually-created rules, ties break on creation order (the older rule wins). The one place a
lower priority is set automatically is the confirm-campaign flow, which writes its
provider_id rule at priority: 10 specifically so an explicit owner pick beats a broad
pattern you wrote earlier.
List, update, and delete
curl "https://app.tease.link/api/admin/source-links" \
-H "Authorization: Bearer $TEASE_API_KEY"Newest first. A team member scoped to specific sources only sees rules targeting their domains.
curl -X PATCH "https://app.tease.link/api/admin/source-links/42" \
-H "Authorization: Bearer $TEASE_API_KEY" -H "Content-Type: application/json" \
-d '{"active": false}'Every field is optional; domain_source/channel/active/notes can change. match_type and
match_value cannot — delete and recreate the rule instead. Setting notes to an explicit
empty string clears it.
curl -X DELETE "https://app.tease.link/api/admin/source-links/42" \
-H "Authorization: Bearer $TEASE_API_KEY"204 on success. You can't touch a rule targeting a domain outside your team scope — it 404s the same way an unknown id would.
The read-only unassigned-links queue
GET /api/admin/unassigned-links lists links the poller has seen traffic on but that no active
rule matches yet — a triage queue, newest-active first. It's read-only from this API; a rule
(or a campaign confirmation) is what clears an entry off it.
What's next
- Confirm the source for a scanned campaign
- Source attribution — where mapped-link rules sit in the priority ladder.