Docs/API Reference

Referral links

Create, list and deactivate no-code referral links, read their stats, and capture leads through the public lead endpoint.

A referral link is a co-branded landing page at https://physioaroundme.com/r/<public_code>. Patients who open it can refer themselves through a short form, and every referral it creates is attributed to you. You can manage links in the Partner Portal under Referral Links, or with the endpoints on this page.

The No-code referral links guide explains the patient experience, consent and attribution in detail.

MethodPath
POST/partners/referral-linksCreate a referral link
GET/partners/referral-linksList referral links
PATCH/partners/referral-links/{id}Update a referral link
POST/public/referral-links/{public_code}/leadsPublic lead capture (no API key)
{
  "object": "referral_link",
  "id": "kx1p9o8i7u6y5t4r3e2w1q0a9s8d7f6g",
  "public_code": "wellah-7KQ2X9MD",
  "url": "https://physioaroundme.com/r/wellah-7KQ2X9MD",
  "campaign_name": "Staff wellness Q4",
  "service_scope": "all_rehabilitation",
  "default_care_mode": "patient_choice",
  "status": "active",
  "environment": "live",
  "expires_at": "2027-01-31T23:59:59.000Z",
  "stats": { "clicks": 0, "leads": 0, "signups": 0, "bookings": 0, "payments": 0 },
  "created_at": "2026-10-13T09:30:00.000Z"
}
FieldTypeDescription
objectstringAlways referral_link.
idstringLink ID. Use it with PATCH /partners/referral-links/{id}.
public_codestringThe non-guessable code in the URL. It contains no patient information.
urlstringThe link to share: https://physioaroundme.com/r/<public_code>.
campaign_namestring or nullYour label for the link.
service_scopestringThe services the link covers, for example all_rehabilitation.
default_care_modestringremote, in_person or patient_choice.
statusstringactive or inactive.
environmentstringsandbox or live. Links inherit the environment of the key that created them.
expires_atstring or nullAfter this time the link behaves as inactive.
statsobjectPerformance counters (see below).
created_atstringISO-8601 UTC.

Stats

StatCounts
clicksUnique visitors. A visitor is counted at most once per 30 minutes, and bots are excluded.
leadsLanding-page forms submitted.
signupsPatient accounts attributed to the link.
bookingsBookings created by attributed patients.
paymentsPaid bookings.
POST /partners/referral-links

All body fields are optional. The link is created in the environment of your API key, so a sk_test_ key creates a sandbox link. Accepts Idempotency-Key.

FieldTypeDescription
campaign_namestringA label for your own reporting, for example Staff wellness Q4.
service_scopestringThe services the link covers, for example all_rehabilitation.
default_care_modestringremote, in_person or patient_choice.
expires_atstringISO-8601 timestamp after which the link stops accepting patients.
curl https://api.physioaroundme.com/v1/partners/referral-links \
  -X POST \
  -H "Authorization: Bearer $REHABIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6d0e3b9a-1c2f-4e8d-a7b6-5c4d3e2f1a0b" \
  -d '{
    "campaign_name": "Staff wellness Q4",
    "service_scope": "all_rehabilitation",
    "default_care_mode": "patient_choice",
    "expires_at": "2027-01-31T23:59:59.000Z"
  }'

Response: 201 Created with the referral link object. New links start with status: "active" and zeroed stats.

Errors: 422 validation_error (for example, an invalid default_care_mode or expires_at), plus the standard authentication errors.

GET /partners/referral-links

Returns your links in the key's environment as a paginated list. Use limit (1–100, default 25) and cursor.

curl "https://api.physioaroundme.com/v1/partners/referral-links?limit=20" \
  -H "Authorization: Bearer $REHABIFY_API_KEY"
200 OK
{
  "object": "list",
  "data": [
    {
      "object": "referral_link",
      "id": "kx1p9o8i7u6y5t4r3e2w1q0a9s8d7f6g",
      "public_code": "wellah-7KQ2X9MD",
      "url": "https://physioaroundme.com/r/wellah-7KQ2X9MD",
      "campaign_name": "Staff wellness Q4",
      "service_scope": "all_rehabilitation",
      "default_care_mode": "patient_choice",
      "status": "active",
      "environment": "live",
      "expires_at": "2027-01-31T23:59:59.000Z",
      "stats": { "clicks": 412, "leads": 37, "signups": 21, "bookings": 14, "payments": 12 },
      "created_at": "2026-10-13T09:30:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
PATCH /partners/referral-links/{id}

Activates or deactivates a link. {id} is the link's id. The body has one field:

FieldTypeDescription
statusstringactive or inactive.

An inactive link shows patients an "unavailable" page, accepts no new leads and doesn't attribute anyone. Its stats and existing attributions are kept.

curl https://api.physioaroundme.com/v1/partners/referral-links/kx1p9o8i7u6y5t4r3e2w1q0a9s8d7f6g \
  -X PATCH \
  -H "Authorization: Bearer $REHABIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "inactive" }'

Response: 200 OK with the updated referral link object.

Errors: 404 referral_link_not_found and 422 validation_error, plus the standard authentication errors.

Public lead capture

POST /public/referral-links/{public_code}/leads

This is the endpoint the hosted landing page submits to. Because it's public, you can also post to it from your own website form:

  • No API key. It's authenticated by the link's public_code only, so never send your secret key here.
  • CORS-enabled, so you can call it from a browser.
  • Rate limited per IP address: 5 requests per 10 minutes. Over the limit, it returns 429 rate_limit_exceeded with Retry-After.
  • The lead becomes a referral in the link's environment. It shows up in your dashboard and the API, fires referral.created, and is attributed to you.

Request body

{
  "patient": {
    "first_name": "Ngozi",
    "last_name": "Eze",
    "phone": "+2348031234567",
    "email": "ngozi@example.com",
    "city": "Abuja",
    "state": "FCT",
    "preferred_language": "en"
  },
  "need": { "reason": "knee_injury", "preferred_care_mode": "patient_choice" },
  "contact": { "preferred_channel": "whatsapp" },
  "consent": { "granted": true, "privacy_notice_version": "2026-09-01" }
}
FieldRules
patient.first_nameRequired.
patient.phone or patient.emailAt least one is required.
patient.last_name, patient.city, patient.stateOptional.
patient.preferred_languageOptional: en, yo, ig or ha.
need.reasonOptional. Why the patient needs care, for example knee_injury.
need.preferred_care_modeOptional: remote, in_person or patient_choice.
contact.preferred_channelOptional: whatsapp, phone, email or sms.
consent.grantedRequired, and must be true. Show an explicit consent checkbox that is unticked by default.
consent.privacy_notice_versionOptional. The version of the privacy notice the patient saw.

Example from a browser

// Runs in the browser. No API key: the public_code identifies your link.
async function submitLead(form) {
  const res = await fetch(
    "https://api.physioaroundme.com/v1/public/referral-links/wellah-7KQ2X9MD/leads",
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        patient: {
          first_name: form.first_name.value,
          phone: form.phone.value,
          city: form.city.value,
        },
        need: { reason: form.reason.value, preferred_care_mode: "patient_choice" },
        contact: { preferred_channel: "whatsapp" },
        consent: { granted: form.consent.checked, privacy_notice_version: "2026-09-01" },
      }),
    }
  );
  const body = await res.json();
  if (!res.ok) throw new Error(body.error.message);
  return body; // show body.tracking_code and a "Chat with Joy on WhatsApp" button (body.whatsapp_intake_url)
}

Responses

201 Created (new lead)
{
  "object": "lead",
  "tracking_code": "RHB-7302918465",
  "status": "received",
  "duplicate": false,
  "tracking_url": "https://physioaroundme.com/track/RHB-7302918465",
  "whatsapp_intake_url": "https://wa.me/2348061525811?text=START%20RHB-7302918465"
}

If the same phone number was already submitted for your organisation in the last 24 hours, no new referral is created, and the response is 200 OK with duplicate: true and no tracking code:

200 OK (duplicate)
{
  "object": "lead",
  "tracking_code": null,
  "status": null,
  "duplicate": true,
  "tracking_url": null,
  "whatsapp_intake_url": null
}
HTTPCodeWhen
201The lead was accepted and a referral was created.
200Duplicate: the same phone was submitted for your organisation in the last 24 hours.
404referral_link_not_foundNo link has this public_code.
410link_inactiveThe link is inactive or expired.
422validation_error, consent_requiredA field is invalid, or consent.granted isn't true.
429rate_limit_exceededMore than 5 requests in 10 minutes from this IP address.
Referral links | Rehabify Docs | Physio Around Me by Rehabify Health