Skip to content New SourceLoop MCP: chat with your attribution data in Claude, ChatGPT & Cursor
SourceLoop
API reference

Docs

Endpoints under /v1/docs. REST endpoints, parameters, and response schemas for the SourceLoop attribution API.

Endpoint Method Path
List docs List docs GET /v1/docs
Create doc Create a doc POST /v1/docs
Get doc Read a doc GET /v1/docs/{id}
Edit doc Edit a doc block by block POST /v1/docs/{id}/blocks
Share doc Create a share link POST /v1/docs/{id}/shares

Base URL https://app.sourceloop.ai/api/v1

List docs

List docs

GET /v1/docs

Any valid API key. No extra scope needed.

Workspace docs (reports, dashboards, plans) and the templates a new doc can start from. Private docs are never listed.

curl -s -X GET "https://app.sourceloop.ai/api/v1/docs?website=acme.com" \
  -H "Authorization: Bearer $SOURCELOOP_API_KEY"
const res = await fetch(
  "https://app.sourceloop.ai/api/v1/docs?website=acme.com",
  {
    method: "GET",
    headers: {
      Authorization: `Bearer ${process.env.SOURCELOOP_API_KEY}`,
    },
  },
);

const data = await res.json();
import os, requests

res = requests.get(
    "https://app.sourceloop.ai/api/v1/docs?website=acme.com",
    headers={"Authorization": f"Bearer {os.environ['SOURCELOOP_API_KEY']}"},
)
data = res.json()

Query parameters

websitestring

Website domain, e.g. acme.com. Required only when the key covers more than one.

Responses

  • 200 Docs and templates

Create doc

Create a doc

POST /v1/docs

Any valid API key. No extra scope needed.

From a `template` key or from `markdown`. Markdown may hold ```sourceloop-widget fences with widget JSON, the format GET /docs/{id} returns. Needs the docs:write scope.

curl -s -X POST "https://app.sourceloop.ai/api/v1/docs" \
  -H "Authorization: Bearer $SOURCELOOP_API_KEY"
const res = await fetch(
  "https://app.sourceloop.ai/api/v1/docs",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SOURCELOOP_API_KEY}`,
    },
  },
);

const data = await res.json();
import os, requests

res = requests.post(
    "https://app.sourceloop.ai/api/v1/docs",
    headers={"Authorization": f"Bearer {os.environ['SOURCELOOP_API_KEY']}"},
)
data = res.json()

Request body

websitestring

titlestring

templatestring

markdownstring

Responses

  • 200 The new doc id and URL
  • 400 Something was wrong with the request or the credential.

Get doc

Read a doc

GET /v1/docs/{id}

Any valid API key. No extra scope needed.

The doc as Markdown, every block with its id, type, text and widget spec, and the doc's controls.

curl -s -X GET "https://app.sourceloop.ai/api/v1/docs/{id}" \
  -H "Authorization: Bearer $SOURCELOOP_API_KEY"
const res = await fetch(
  "https://app.sourceloop.ai/api/v1/docs/{id}",
  {
    method: "GET",
    headers: {
      Authorization: `Bearer ${process.env.SOURCELOOP_API_KEY}`,
    },
  },
);

const data = await res.json();
import os, requests

res = requests.get(
    "https://app.sourceloop.ai/api/v1/docs/{id}",
    headers={"Authorization": f"Bearer {os.environ['SOURCELOOP_API_KEY']}"},
)
data = res.json()

Path parameters

idstringpathrequired

Responses

  • 200 The doc
  • 404 Something was wrong with the request or the credential.

Edit doc

Edit a doc block by block

POST /v1/docs/{id}/blocks

Any valid API key. No extra scope needed.

Ops: append, insert_after, insert_before, replace, remove, move_after. Applied as one change that merges with live editing; a restore point is saved first. There is no whole-document replace.

curl -s -X POST "https://app.sourceloop.ai/api/v1/docs/{id}/blocks" \
  -H "Authorization: Bearer $SOURCELOOP_API_KEY"
const res = await fetch(
  "https://app.sourceloop.ai/api/v1/docs/{id}/blocks",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SOURCELOOP_API_KEY}`,
    },
  },
);

const data = await res.json();
import os, requests

res = requests.post(
    "https://app.sourceloop.ai/api/v1/docs/{id}/blocks",
    headers={"Authorization": f"Bearer {os.environ['SOURCELOOP_API_KEY']}"},
)
data = res.json()

Path parameters

idstringpathrequired

Request body

opsobject[]

Responses

  • 200 Ids of inserted blocks
  • 400 Something was wrong with the request or the credential.

Share doc

Create a share link

POST /v1/docs/{id}/shares

Any valid API key. No extra scope needed.

A link that opens the doc in the workspace brand without signing in. The URL is returned once. Needs the docs:share scope.

curl -s -X POST "https://app.sourceloop.ai/api/v1/docs/{id}/shares" \
  -H "Authorization: Bearer $SOURCELOOP_API_KEY"
const res = await fetch(
  "https://app.sourceloop.ai/api/v1/docs/{id}/shares",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SOURCELOOP_API_KEY}`,
    },
  },
);

const data = await res.json();
import os, requests

res = requests.post(
    "https://app.sourceloop.ai/api/v1/docs/{id}/shares",
    headers={"Authorization": f"Bearer {os.environ['SOURCELOOP_API_KEY']}"},
)
data = res.json()

Path parameters

idstringpathrequired

Request body (optional)

fixed_windowstring

The period the link always shows: "previous month" (moves forward each month) or "2026-10-01..2026-10-31". Omit to follow the doc.

allow_date_changeboolean

Whether viewers may change the date range. Defaults to false with fixed_window, true without.

titlestring

What the shared page is called for its viewers. Defaults to the doc title.

passwordstring

show_contact_detailsboolean

Full emails and phone numbers in lists of people. Needs a password. Off by default; masked otherwise.

expires_atstring (date-time)

Responses

  • 200 The share URL
  • 400 An invalid period, password or expiry, with a message saying which

Track every conversion to its true source

Capture and send full attribution data from every signup, lead, booking, and sale to your CRM and ad platforms, so you know exactly what's driving revenue.

Without SourceLoop

Untagged

Kayden Floyd

kayden@abc.com

  • SourceUnknown
  • MediumUnknown
  • CampaignUnknown
  • Landing pageUnknown
Journey
No touchpoints captured

With SourceLoop

Auto-tagged

Kayden Floyd

kayden@abc.com · Acme Co.

  • Channel Paid Social
  • CampaignFree_demo
  • Landing page/pricing
Journey
Synced to HubSpot Google Ads Meta