---
title: "Publisher Claim Info By Slug"
method: GET
path: "/v1/publisher/by-slug/{tenant_slug}/claim-info"
---

# Publisher Claim Info By Slug

`GET /v1/publisher/by-slug/{tenant_slug}/claim-info`

## Request

- Base URL: `https://api.storyflo.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.storyflo.com/v1/publisher/by-slug/{tenant_slug}/claim-info`
- Auth: none declared

Public-by-slug lookup so the referral-style claim URL
(/publisher/claim/auto?ref=<slug>, sent by already-claimed authors
to their peers) can resolve to a real claim link without leaking
a hot claim_token in the email body.

Returns a never-fails 200 with `{exists, name, claim_url, claimed,
latest_article_slug}`. When the publisher doesn't exist at all we
return `exists=False` so the landing page can show a friendly 'we
don't have this newsletter yet, forward us an issue' CTA.

🚨 MEASURED ACCOUNT-TAKEOVER (2026-09-14). This endpoint has no auth
dependency, and it used to mint a fresh ``claim_token`` whenever the
publisher didn't already carry one. A SUCCESSFUL CLAIM POPS THAT KEY
(``rj.pop("claim_token", None)`` in ``publisher_claim_accept``), so
"doesn't already carry one" is the state of every publisher who has
ALREADY CLAIMED. The burn was real and this undid it: an anonymous
GET knowing only a tenant_slug minted a live token, and redeeming it
mints an ``access_token`` — the dashboard credential — and writes a
fresh ``distribution_authorization`` in that author's name.

Two gates now, in this order:

1. A publisher that has claimed NEVER gets a URL and NEVER gets a
   mint. ``claimed`` is the same predicate the creator feed uses
   (``opt_in_at`` OR ``raw_json.claimed_at``), so a publisher
   onboarded before ``claimed_at`` existed is covered too.
2. Taken-down and do-not-contact publishers 404 rather than
   answering at all — copied verbatim from the creator-feed builder
   so the two surfaces cannot drift.

✅ CLOSED 2026-09-15: this endpoint no longer mints AT ALL. A claim
token is ISSUED, on exactly two occasions, and neither of them is
somebody reading a slug:

  invite       — every outreach path mints one and mails it to the
                 publisher's OWN address.
  registration — ``/v1/publisher/onboard`` mints an ``access_token``
                 and returns it; a publisher who signs themselves up
                 is already in and needs no claim link.

Tier is decided after that, on activation. Issuance is not the place
to express it, which is what minting-on-read was quietly doing.

## Path parameters

- `tenant_slug` string, required

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/storyflo/apis/storyflo-inference-router.md) · [All operations](https://skmtc.dev/storyflo/apis/storyflo-inference-router/llms.txt) · [OpenAPI document](https://skmtc.dev/storyflo/apis/storyflo-inference-router/revisions/c3a1a735ac7a?raw)
