← All action domains

Links

28 operations. Call each with POST https://app.chirply.io/api/v1/actions/<name> and a bearer token; the response is { "data": { "action", "summary", "result" } }. A read badge means the operation changes nothing; write requires the credential’s write scope.

Recent clicks

links.clicksread

The most recent individual clicks on a link — when, from which country and city, on what device and browser, where they came from, and whether they were sent through or stopped by a rule.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to look at.
limitintegeroptionalHow many clicks to return. Default: 50

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.clicks \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_clicks at https://app.chirply.io/api/mcp, same bearer token, same input.

Connect a domain

links.connect_domainwriteconfirmadmin only

DEPRECATED — use domains.connect, which writes the same rows and is the maintained version. Registers a domain the organization owns so links and pages can be served on it. Creates a Cloudflare custom hostname and starts certificate issuance; the domain will NOT serve anything until the owner adds a CNAME record at their DNS provider and the certificate is issued. Nothing is charged, but this claims the hostname on the platform's Cloudflare zone.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
domainstringrequiredThe hostname to connect, e.g. 'go.acme.com'. No scheme, no path.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.connect_domain \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example"
  }'
Test with your API key

Over MCP the same operation is the tool links_connect_domain at https://app.chirply.io/api/mcp, same bearer token, same input.

Create a link

links.createwrite

Create a link and return its public URL. Costs nothing and sends nothing — the link is live immediately but nobody sees it until it is shared. Leave the name blank for a short random one. Leave domain_id blank to host it on the platform's own short address; supply one of the organization's connected domains to brand it. Rotating, sticky and overflow links need `targets`; a file link needs a file URL. To turn one natural-language brief into both an opt-in link and an AI-designed editable page, use links.generate_optin_page instead.

Parameters

FieldTypeRequiredDescription
kind"short" | "rotating" | "sticky" | "overflow" | "group" | "file" | … 3 moreoptionalWhat the link does. 'short' sends everyone to one place. 'rotating' splits traffic between several destinations; 'sticky' does the same but a returning visitor keeps their original destination; 'overflow' fills each destination up to its own click cap before moving to the next. 'group' is a folder that reports on its child links. 'file' serves an uploaded file. 'optin' shows an email-capture form first and creates a CRM contact. 'bio' renders a link-in-bio profile page. 'untracked' is a plain redirect with NO click logging at all. Default: "short"
destinationstringoptionalWhere the link sends people. Required for every kind except group, bio and file.
slugstringoptionalThe part after the slash, e.g. 'spring-sale'. Random if omitted. This IS the public URL: changing it on an existing link 404s every copy already shared, printed or sent.
domain_idstring (uuid) (or null)optionalA connected domain to host the link on. Null = the platform's own short address.
parent_idstring (uuid) (or null)optionalThe id of a kind='group' link to file this one under. The group reports the combined clicks and conversions of everything inside it; the child keeps its own URL and its own report.
titlestringoptionalAn internal label for lists and reports. Visitors never see it — not on the page, not in the browser tab, not in a share card. Set `preview` to control what the public sees when the link is posted somewhere.
notesstringoptionalPrivate notes.
tagsstring[]optionalTags for grouping links.
status"active" | "paused" | "archived"optional'active' resolves normally; 'paused' and 'archived' stop the link dead — visitors get a not-found page.
targetsobject[]optionalDestinations for a rotating, sticky or overflow link.
targets[].urlstringrequiredWhere this destination sends people.
targets[].labelstringoptionalA name for this destination, for reports.
targets[].weightintegeroptionalShare of traffic relative to the other destinations. Two at 1 each split evenly; one at 3 against one at 1 takes three quarters. Ignored by overflow links.
targets[].capinteger (or null)optionalOverflow links only: how many clicks this destination absorbs before traffic spills into the next one.
targets[].activebooleanoptionalSet false to skip this destination.
passwordstringoptionalVisitors must type this before the link works. Omit for none.
starts_atstring (date-time)optionalISO 8601 timestamp before which the link doesn't work yet.
expires_atstring (date-time)optionalISO 8601 timestamp after which the link stops working.
expired_urlstringoptionalWhere expired traffic goes. Omit to show a plain message instead.
max_clicksintegeroptionalStop resolving after this many clicks.
strip_fbclidbooleanoptionalRemove the `fbclid` parameter Facebook appends before forwarding.
forward_querybooleanoptionalPass the visitor's query string on to the destination. Default true.
redirect_codeintegeroptional301 or 302. 301 is cached by browsers forever — later destination changes may not reach people who already clicked.
schedulemap of string → objectoptionalDifferent destinations on different days. {"days":{"mon":"https://…"},"dates":{"2026-12-25":"https://…"},"timezone":"America/New_York"}. An exact date beats a weekday.
geomap of string → objectoptionalCountry rules. {"mode":"off|allow|deny|route","countries":{"US":{"url":"https://…"}},"blockedUrl":"https://…"}. allow = only these countries get through; deny = these are blocked; route = everyone gets through but these go elsewhere.
devicemap of string → objectoptionalPer-device destinations. {"ios":"…","android":"…","desktop":"…"}.
previewmap of string → objectoptionalOverrides the social share card. {"enabled":true,"title":"…","description":"…","image":"https://…"}.
interstitialmap of string → objectoptionalThe branded waiting page. {"enabled":true,"seconds":5,"headline":"…","message":"…","logoUrl":"…","color":"#1155cc"}. Forced on whenever a retargeting pixel is attached, because that page is the only place a pixel can fire.
optinmap of string → objectoptionalOpt-in gate configuration for kind=optin. {"headline":"…","message":"…","buttonLabel":"…","fields":{"name":{"show":true,"required":false},"phone":{"show":false}},"tags":["newsletter"],"disclaimer":"…","color":"#1155cc","design":{"mode":"basic|builder","funnelId":"uuid","pageId":"uuid"},"confirmation":{"enabled":true,"method":"link|code","channels":["email","phone"],"emailIdentityId":"uuid (optional)","phoneNumberId":"uuid (optional)","subject":"Confirm your signup","message":"…","buttonLabel":"Confirm","smsMessage":"…","pendingMessage":"…"}}. The basic design is built in; use links.design_optin_page to safely create builder ids for an existing link, or links.generate_optin_page to create the link and AI-designed builder draft together from one brief. Email is always collected. Double opt-in uses exactly one method and delivers it by email, SMS, or both. Omitted sender IDs use account defaults; explicit IDs must be ready/active account senders. Delivery sends real messages through the account providers and incurs their normal cost. No CRM contact, source tags, conversion, or automation is created until verification succeeds.
biomap of string → objectoptionalBio page contents for kind=bio. {"heading":"…","tagline":"…","avatarUrl":"…","theme":"light|dark","color":"#1155cc","buttons":[{"label":"…","url":"…"}],"socials":[{"network":"instagram","url":"…"}]}.
filemap of string → objectoptionalThe file a kind=file link serves. {"url":"https://…","name":"guide.pdf","download":true}. Uploading a file is UI-only; supply a URL here.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.create \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "short",
    "destination": "example"
  }'
Test with your API key

Over MCP the same operation is the tool links_create at https://app.chirply.io/api/mcp, same bearer token, same input.

Add a retargeting pixel

links.create_pixelwriteconfirmadmin only

DEPRECATED — use pixels.create, which writes the same rows and is the maintained version. Adds a retargeting pixel that can be attached to links. Supply the provider's own ID (from Meta Events Manager, Google Ads, and so on) — the snippet is generated from it. Use provider 'custom' with `custom_html` for anything else, which injects THAT HTML VERBATIM INTO A PUBLIC PAGE every visitor passing through the link loads: it is arbitrary third-party JavaScript running on the organization's own branded domain, and there is no review step. `scripts.create` is confirmed for exactly this payload.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
namestringrequiredA name so you can find it later.
provider"facebook" | "google_ads" | "google_analytics" | "tiktok" | "linkedin" | "pinterest" | … 4 morerequiredWhich ad platform the pixel belongs to.
pixel_idstringoptionalThe provider's own pixel or measurement ID. Required unless provider is 'custom'.
custom_htmlstringoptionalRaw snippet, for provider 'custom' only. Injected as-is.
placement"head" | "body"optionalWhere in the waiting page the snippet goes. Default: "head"

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.create_pixel \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Example",
    "provider": "facebook"
  }'
Test with your API key

Over MCP the same operation is the tool links_create_pixel at https://app.chirply.io/api/mcp, same bearer token, same input.

Add a traffic seller

links.create_vendorwrite

Add someone this organization buys clicks from. Assign them to a link (with clicks_ordered and order_amount) to see how much of what was paid for actually arrived.

Parameters

FieldTypeRequiredDescription
namestringrequiredWho you buy from.
emailstringoptionalTheir email address.
websitestringoptionalTheir website.
notesstringoptionalPrivate notes about them.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.create_vendor \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Example"
  }'
Test with your API key

Over MCP the same operation is the tool links_create_vendor at https://app.chirply.io/api/mcp, same bearer token, same input.

Delete a link

links.deletewriteconfirm

Permanently delete a link, along with every click and conversion recorded against it. Anyone who already has the link gets a not-found page from then on. This cannot be undone — pause the link instead if you only want to stop it temporarily.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to delete.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.delete \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_delete at https://app.chirply.io/api/mcp, same bearer token, same input.

Delete a retargeting pixel

links.delete_pixelwriteconfirmadmin only

DEPRECATED — use pixels.delete, which deletes the same rows and is the maintained version. Permanently deletes a retargeting pixel and removes it from every link it was attached to. Those links stop building that audience from the next click on. This cannot be undone.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe pixel to delete.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.delete_pixel \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_delete_pixel at https://app.chirply.io/api/mcp, same bearer token, same input.

Delete a traffic seller

links.delete_vendorwriteconfirm

Permanently delete a traffic seller. Links assigned to them keep working and keep their ordered-click figures, but are no longer grouped under anyone. This cannot be undone.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe seller to delete.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.delete_vendor \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_delete_vendor at https://app.chirply.io/api/mcp, same bearer token, same input.

Design in Page Builder

links.design_optin_pagewrite

Create or reopen the dedicated drag-and-drop page for an opt-in link. This uses one page/funnel slot when first created, sends no messages, and does not change what visitors see until the page is published. The visual page controls layout and content while LinkWizard continues to control captured details, verification, account senders, tags, automations, and the final destination.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe opt-in link whose visual page should be created or opened.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.design_optin_page \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_design_optin_page at https://app.chirply.io/api/mcp, same bearer token, same input.

Duplicate a link

links.duplicatewrite

Copy a link with all of its rules and destinations under a fresh random name. The copy is created PAUSED on purpose — an exact duplicate that went live immediately would start splitting traffic with the original before anything had been changed. Retargeting pixels are not copied.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to copy.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.duplicate \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_duplicate at https://app.chirply.io/api/mcp, same bearer token, same input.

Turn on conversion tracking

links.enable_trackingwriteconfirm

Switch on full-loop conversion tracking and return the one script to install. Once on, every tracked link appends a small `cwc` parameter to the DESTINATION URL — the organization's live public links start carrying an extra query parameter to whatever site they point at, which some destinations reject or log. THERE IS NO CAPABILITY TO TURN THIS BACK OFF: once an account has a tracker it keeps it, so this is one-way from the machine surfaces. Safe to call repeatedly — it returns the existing token if there is one.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

No parameters — POST an empty body.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.enable_tracking \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{}'
Test with your API key

Over MCP the same operation is the tool links_enable_tracking at https://app.chirply.io/api/mcp, same bearer token, same input.

Build opt-in with AI

links.generate_optin_pagewriteconfirm

Create a working LinkWizard opt-in link and an AI-designed, fully editable Page Builder draft from one plain-language brief. The link itself is active immediately and its built-in fallback form works, but the AI design does NOT replace that fallback until a human publishes the builder page. This SPENDS MONEY — the generation is billed to the organization's own AI provider key — and it uses one page/funnel slot against the plan's limit. It sends no messages and applies no tags or automations until a real visitor submits the form.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
promptstringrequiredDescribe the offer, audience, desired look and conversion goal in plain language. The AI writes and lays out an opt-in page from this brief.
destinationstringrequiredFull URL visitors should reach after they submit and complete any required verification, such as https://example.com/guide.
slugstringoptionalPreferred public link name after the slash. A short random name is used if omitted.
domain_idstring (uuid) (or null)optionalActive connected domain that should host the link. Null or omitted uses the platform's own short-link domain.
titlestringoptionalInternal name shown in LinkWizard. If omitted, the opening sentence of the brief is used.
tagsstring[]optionalCRM tags to apply when a visitor successfully completes the opt-in.
collect_namebooleanoptionalShow a name field on the form. Default: true
require_namebooleanoptionalRequire the name field. Ignored when collect_name is false. Default: false
collect_phonebooleanoptionalShow a phone field on the form in addition to the always-required email field. Default: false
require_phonebooleanoptionalRequire the phone field. Ignored when collect_phone is false. Default: false
disclaimerstringoptionalConsent or privacy text displayed beside the form submission control.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.generate_optin_page \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "example",
    "destination": "example"
  }'
Test with your API key

Over MCP the same operation is the tool links_generate_optin_page at https://app.chirply.io/api/mcp, same bearer token, same input.

Open a link

links.getread

Fetch one link by id with all of its rules, its rotation destinations and the retargeting pixels attached to it, plus its public URL.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link's id.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.get \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_get at https://app.chirply.io/api/mcp, same bearer token, same input.

Cross-account contact sharing

links.get_contact_sharingread

Whether this account lets OTHER accounts read contact context for people it sent to them on a tracked link, and which accounts may do it. Relevant when this account's contacts click through to a landing page somebody else owns — an affiliate or partner arrangement. Off by default. Read-only.

Parameters

No parameters — POST an empty body.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.get_contact_sharing \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{}'
Test with your API key

Over MCP the same operation is the tool links_get_contact_sharing at https://app.chirply.io/api/mcp, same bearer token, same input.

Conversion tracking snippet

links.get_trackingread

The organization's conversion-tracking state, every website it tracks with the script tag for each, and the custom event names already seen. There is ONE script (`/embed/t.js`) which does visitor tracking and conversions together — there is no separate conversion-only snippet any more — but each website carries its OWN key, because that key is what scopes the site's origin allow-list and keeps one site's visitors out of another's reports. So `sites` is a list and there is deliberately no one default snippet: handing out one site's key for a different site produces beacons the origin allow-list refuses. Returns nothing configured if tracking has never been switched on.

Parameters

No parameters — POST an empty body.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.get_tracking \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{}'
Test with your API key

Over MCP the same operation is the tool links_get_tracking at https://app.chirply.io/api/mcp, same bearer token, same input.

List links

links.listread

List the organization's links, newest first, with their click, unique-visitor and conversion counts. Optionally filter by kind, status, domain or tag, and search the name, label and destination.

Parameters

FieldTypeRequiredDescription
limitintegeroptionalMax rows to return (1–100). Default: 25
offsetintegeroptionalRows to skip. Default: 0
kind"short" | "rotating" | "sticky" | "overflow" | "group" | "file" | … 3 moreoptionalWhat the link does. 'short' sends everyone to one place. 'rotating' splits traffic between several destinations; 'sticky' does the same but a returning visitor keeps their original destination; 'overflow' fills each destination up to its own click cap before moving to the next. 'group' is a folder that reports on its child links. 'file' serves an uploaded file. 'optin' shows an email-capture form first and creates a CRM contact. 'bio' renders a link-in-bio profile page. 'untracked' is a plain redirect with NO click logging at all.
status"active" | "paused" | "archived"optional'active' resolves normally; 'paused' and 'archived' stop the link dead — visitors get a not-found page.
domain_idstring (uuid)optionalOnly links on this connected domain.
tagstringoptionalOnly links carrying this tag.
querystringoptionalText to match in the link name, label or destination.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.list \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "limit": 25,
    "offset": 0
  }'
Test with your API key

Over MCP the same operation is the tool links_list at https://app.chirply.io/api/mcp, same bearer token, same input.

List retargeting pixels

links.list_pixelsread

DEPRECATED — use pixels.list, which reads the same rows and is the maintained version. Lists the retargeting pixels set up for this organization, ready to attach to links.

Parameters

No parameters — POST an empty body.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.list_pixels \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{}'
Test with your API key

Over MCP the same operation is the tool links_list_pixels at https://app.chirply.io/api/mcp, same bearer token, same input.

List traffic sellers

links.list_vendorsread

List the people this organization buys clicks from, for assigning to links and tracking delivery against what was ordered.

Parameters

No parameters — POST an empty body.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.list_vendors \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{}'
Test with your API key

Over MCP the same operation is the tool links_list_vendors at https://app.chirply.io/api/mcp, same bearer token, same input.

Links overview

links.overviewread

Totals across every link in the organization: how many links, how many clicks and how many conversions.

Parameters

No parameters — POST an empty body.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.overview \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{}'
Test with your API key

Over MCP the same operation is the tool links_overview at https://app.chirply.io/api/mcp, same bearer token, same input.

Who a link was sent to

links.recipientsread

The people this link was sent to individually, and which of them opened it — highest engagement first. Only populated when per-person link tracking is on: each recipient of an email or text gets their own copy of the link, so a click can be attributed to a named contact rather than an anonymous visitor.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to look at.
limitintegeroptionalHow many recipients to return. Default: 50

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.recipients \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_recipients at https://app.chirply.io/api/mcp, same bearer token, same input.

Share contacts with partner sites

links.set_contact_sharingwriteconfirmadmin only

Let other accounts read the CRM context — name, email, tags, deals, messages, and call transcripts — of a contact of yours who clicked one of your tracked links onto THEIR landing page. This discloses your own customers' personal data to another business: they can use it to personalize the page that contact lands on. It never works in reverse, only applies to contacts who actually clicked one of your links, and turning it off takes effect immediately for every future request. Leave `destination_org_ids` empty to allow any destination (the usual choice for a public affiliate program); list account ids to restrict it to a named few.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
enabledbooleanrequiredtrue lets permitted destination accounts read your contacts' context; false stops it for every future request.
destination_org_idsarray of (string (uuid))optionalThe only accounts allowed to read it. Omit or pass an empty list to allow any site your tracked links point at.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.set_contact_sharing \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true
  }'
Test with your API key

Over MCP the same operation is the tool links_set_contact_sharing at https://app.chirply.io/api/mcp, same bearer token, same input.

Choose which pixels fire on a link

links.set_pixelswriteconfirmadmin only

DEPRECATED — use pixels.attach, which writes the same rows and is the maintained version. Sets exactly which retargeting pixels fire on a link, replacing whatever was attached before. This changes what a LIVE public link does: attaching any pixel forces the link to show its short branded waiting page — that page is the only moment a pixel can fire on a click passing through to somebody else's site — and it starts running that pixel's third-party JavaScript for every visitor.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to change.
pixel_idsarray of (string (uuid))requiredThe complete list of pixels for this link. An empty array removes them all.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.set_pixels \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11",
    "pixel_ids": [
      "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
    ]
  }'
Test with your API key

Over MCP the same operation is the tool links_set_pixels at https://app.chirply.io/api/mcp, same bearer token, same input.

Pause or resume a link

links.set_statuswriteconfirm

Set a link live, paused or archived. A paused link stops resolving immediately — everyone who opens it, including people who already have it, gets a not-found page.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to change.
status"active" | "paused" | "archived"required'active' resolves normally; 'paused' and 'archived' stop the link dead — visitors get a not-found page.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.set_status \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11",
    "status": "active"
  }'
Test with your API key

Over MCP the same operation is the tool links_set_status at https://app.chirply.io/api/mcp, same bearer token, same input.

Link report

links.statsread

Click and conversion statistics for one link over a window of days: totals, unique visitors, blocked clicks, conversions and their value, a per-day series, and rankings by country, device, browser, operating system and referring site.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to report on.
daysintegeroptionalHow many days back to include. Default: 30

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.stats \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_stats at https://app.chirply.io/api/mcp, same bearer token, same input.

Edit a link

links.updatewriteconfirm

Update any field on an existing link. Omitted fields are left alone. THREE OF THESE FIELDS REACH THE PUBLIC IMMEDIATELY. `slug` and `domain_id` change the link's public URL, so every copy already shared, printed, emailed or posted to an ad platform starts returning a not-found page. `status` is the same write `links.set_status` gates: 'paused' or 'archived' kills the link dead for everyone holding it. And supplying `targets` REPLACES the whole destination list, which resets the per-destination click counts that overflow caps rely on. None of that can be undone by editing the field back — traffic lost in the meantime is gone.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe link to edit.
kind"short" | "rotating" | "sticky" | "overflow" | "group" | "file" | … 3 moreoptionalWhat the link does. 'short' sends everyone to one place. 'rotating' splits traffic between several destinations; 'sticky' does the same but a returning visitor keeps their original destination; 'overflow' fills each destination up to its own click cap before moving to the next. 'group' is a folder that reports on its child links. 'file' serves an uploaded file. 'optin' shows an email-capture form first and creates a CRM contact. 'bio' renders a link-in-bio profile page. 'untracked' is a plain redirect with NO click logging at all.
destinationstring (or null)optionalWhere the link sends people. Required for every kind except group, bio and file.
slugstringoptionalThe part after the slash, e.g. 'spring-sale'. Random if omitted. This IS the public URL: changing it on an existing link 404s every copy already shared, printed or sent.
domain_idstring (uuid) (or null)optionalA connected domain to host the link on. Null = the platform's own short address.
parent_idstring (uuid) (or null)optionalThe id of a kind='group' link to file this one under. The group reports the combined clicks and conversions of everything inside it; the child keeps its own URL and its own report.
titlestring (or null)optionalAn internal label for lists and reports. Visitors never see it — not on the page, not in the browser tab, not in a share card. Set `preview` to control what the public sees when the link is posted somewhere.
notesstring (or null)optionalPrivate notes.
tagsstring[]optionalTags for grouping links.
status"active" | "paused" | "archived"optional'active' resolves normally; 'paused' and 'archived' stop the link dead — visitors get a not-found page.
targetsobject[]optionalDestinations for a rotating, sticky or overflow link.
targets[].urlstringrequiredWhere this destination sends people.
targets[].labelstringoptionalA name for this destination, for reports.
targets[].weightintegeroptionalShare of traffic relative to the other destinations. Two at 1 each split evenly; one at 3 against one at 1 takes three quarters. Ignored by overflow links.
targets[].capinteger (or null)optionalOverflow links only: how many clicks this destination absorbs before traffic spills into the next one.
targets[].activebooleanoptionalSet false to skip this destination.
passwordstring (or null)optionalVisitors must type this before the link works. Omit for none.
starts_atstring (date-time) (or null)optionalISO 8601 timestamp before which the link doesn't work yet.
expires_atstring (date-time) (or null)optionalISO 8601 timestamp after which the link stops working.
expired_urlstring (or null)optionalWhere expired traffic goes. Omit to show a plain message instead.
max_clicksinteger (or null)optionalStop resolving after this many clicks.
strip_fbclidbooleanoptionalRemove the `fbclid` parameter Facebook appends before forwarding.
forward_querybooleanoptionalPass the visitor's query string on to the destination. Default true.
redirect_codeintegeroptional301 or 302. 301 is cached by browsers forever — later destination changes may not reach people who already clicked.
schedulemap of string → objectoptionalDifferent destinations on different days. {"days":{"mon":"https://…"},"dates":{"2026-12-25":"https://…"},"timezone":"America/New_York"}. An exact date beats a weekday.
geomap of string → objectoptionalCountry rules. {"mode":"off|allow|deny|route","countries":{"US":{"url":"https://…"}},"blockedUrl":"https://…"}. allow = only these countries get through; deny = these are blocked; route = everyone gets through but these go elsewhere.
devicemap of string → objectoptionalPer-device destinations. {"ios":"…","android":"…","desktop":"…"}.
previewmap of string → objectoptionalOverrides the social share card. {"enabled":true,"title":"…","description":"…","image":"https://…"}.
interstitialmap of string → objectoptionalThe branded waiting page. {"enabled":true,"seconds":5,"headline":"…","message":"…","logoUrl":"…","color":"#1155cc"}. Forced on whenever a retargeting pixel is attached, because that page is the only place a pixel can fire.
optinmap of string → objectoptionalOpt-in gate configuration for kind=optin. {"headline":"…","message":"…","buttonLabel":"…","fields":{"name":{"show":true,"required":false},"phone":{"show":false}},"tags":["newsletter"],"disclaimer":"…","color":"#1155cc","design":{"mode":"basic|builder","funnelId":"uuid","pageId":"uuid"},"confirmation":{"enabled":true,"method":"link|code","channels":["email","phone"],"emailIdentityId":"uuid (optional)","phoneNumberId":"uuid (optional)","subject":"Confirm your signup","message":"…","buttonLabel":"Confirm","smsMessage":"…","pendingMessage":"…"}}. The basic design is built in; use links.design_optin_page to safely create builder ids for an existing link, or links.generate_optin_page to create the link and AI-designed builder draft together from one brief. Email is always collected. Double opt-in uses exactly one method and delivers it by email, SMS, or both. Omitted sender IDs use account defaults; explicit IDs must be ready/active account senders. Delivery sends real messages through the account providers and incurs their normal cost. No CRM contact, source tags, conversion, or automation is created until verification succeeds.
biomap of string → objectoptionalBio page contents for kind=bio. {"heading":"…","tagline":"…","avatarUrl":"…","theme":"light|dark","color":"#1155cc","buttons":[{"label":"…","url":"…"}],"socials":[{"network":"instagram","url":"…"}]}.
filemap of string → objectoptionalThe file a kind=file link serves. {"url":"https://…","name":"guide.pdf","download":true}. Uploading a file is UI-only; supply a URL here.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.update \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_update at https://app.chirply.io/api/mcp, same bearer token, same input.

Change a domain's settings

links.update_domainwriteconfirmadmin only

DEPRECATED — use domains.update, which writes the same rows and is the maintained version. Sets what a connected domain serves: which funnel or single page is attached, where the bare domain redirects when nothing is attached, where unknown addresses go, and whether links are allowed on it at all. This reconfigures a LIVE public hostname: setting links_enabled false immediately stops every link hosted there from resolving, for everyone already holding one, and repointing funnel_id changes what the world sees at that address.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe connected domain to change.
funnel_idstring (uuid) (or null)optionalThe funnel or single page served at the root of this domain. Null for links only.
root_redirect_urlstring (or null)optionalWhere the bare domain sends people when no funnel is attached.
not_found_urlstring (or null)optionalWhere an unknown address on this domain sends people instead of showing a not-found page.
links_enabledbooleanoptionalWhether links may be hosted on this domain.
labelstring (or null)optionalA private label for the domain.

Example

curl -X POST https://app.chirply.io/api/v1/actions/links.update_domain \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool links_update_domain at https://app.chirply.io/api/mcp, same bearer token, same input.

The machine-readable version of this page is GET https://app.chirply.io/api/v1/actions?domain=links — same operations, with full JSON Schemas. Authentication, errors and rate limits are covered in the API documentation home.