> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer share link returns not found

> Decode the identical 404 a customer sees on a signed callback link, a help-center article or ticket link, or a community and ideas board link: expired or forged token, unpublished resource, or disabled surface, with the per-surface ladder and the re-issue checklist.

# Customer share link returns not found

Orbit hands your end customers signed, self-serve links on several public
surfaces:

* **Callback tracking links** (`GET|POST /api/v1/public/callbacks/:token/*`)
  let a caller read status, cancel, or reschedule a queued callback without
  an account.
* **Help-center articles and the ticket portal** (`/public/help/*?org=<slug>`)
  serve your published knowledge base and ticket status to visitors.
* **Community and idea boards** (`/public/community/*`,
  `/public/ideas/*?org=<slug>`) expose your tenant's public boards.

When a customer opens one of these links and it says not found, the person
who can actually fix it is you, the operator, usually forwarding a customer
complaint. This runbook decodes the family: `CALLBACK_NOT_FOUND`,
`ORG_NOT_FOUND`, `ARTICLE_NOT_FOUND`, `TICKET_NOT_FOUND`,
`COMMUNITY_NOT_FOUND`, and `IDEAS_NOT_FOUND`.

## The shared 404 semantics

Every surface above collapses three different causes into the same 404 by
design:

1. **Unknown or expired token or slug.** The identifier never existed, was
   copied wrong, or aged out.
2. **Unpublished or expired resource.** The record exists in your tenant but
   is draft, unpublished, or no longer public.
3. **Disabled surface.** Your organization is not `ACTIVE`, or the surface's
   feature toggle is off for your workspace.

The public endpoint deliberately returns one outcome for all three. It must
not tell a stranger whether a resource exists, what state it is in, or
whether a tenant is enabled, so the 404 itself is not an oracle and no
amount of retrying splits the causes. Triage instead happens per surface,
against your authenticated tenant controls. The short-link sibling of this
family is covered separately in
[Short link not resolving or LINK\_NOT\_FOUND](https://docs.orbit.devotel.io/troubleshooting/short-links-not-resolving.md).

## Per-surface ladders

### Callback links: `CALLBACK_NOT_FOUND`

The token in a callback link is a signed grant that embeds the callback id
and your tenant. Work the ladder:

1. **Copy damage.** The URL was retyped or truncated while forwarding. Copy
   the exact link from the original dispatch notification or SMS; tokens are
   opaque and case-sensitive.
2. **Expired token.** Callback links live a week. A link older than that
   returns the same 404; re-issue the link server-side if the callback still
   needs customer action.
3. **Row gone.** A callback that completed or was purged no longer resolves.
   Read the callback by the id your server stored at creation to confirm its
   outcome.
4. **Already canceled is not this error.** A re-tap of cancel on a canceled
   callback acknowledges `already canceled` as a success, not a 404. A
   customer who sees not found holds a token that does not resolve; the
   callback was not canceled through that link.

### Help center and ticket portal: `ORG_NOT_FOUND`, `ARTICLE_NOT_FOUND`, `TICKET_NOT_FOUND`

* `ORG_NOT_FOUND`: the `?org=` slug matches no `ACTIVE` organization. Pass
  the workspace slug, not the display name; a suspended org also collapses
  here.
* `ARTICLE_NOT_FOUND`: the article is unknown to the portal, no longer
  `ready` (published), not flagged public, or its category is not public.
  All four render the same 404, so an article you unpublished an hour ago
  404s for every visitor immediately.
* `TICKET_NOT_FOUND`: the ticket-status portal could not authorise and
  resolve the ticket from the id and token pair in the link; a forwarded or
  truncated link loses that pairing.

### Community and ideas boards: `COMMUNITY_NOT_FOUND`, `IDEAS_NOT_FOUND`

Unknown org and a disabled feature toggle collapse into the same 404.
Confirm the workspace slug is `ACTIVE`, then confirm the community or ideas
feature is enabled for your tenant. Re-enabling the toggle restores the same
URL; nothing needs re-issuing.

## Operator checklist to re-issue a link

1. **Name the surface from the URL.** `/api/v1/public/callbacks/<token>` is
   a callback; `/public/help/articles/<slug>` or `/help?org=` is the help
   center; `/public/community` or `/public/ideas` is a board.
2. **Check your tenant state** in the authenticated console: organization
   `ACTIVE`, and the surface's feature enabled.
3. **Check the resource state**: the callback id you stored still exists and
   is not terminal; the article is `ready`, flagged public, in a public
   category; the ticket exists.
4. **If state is good, the link copy is bad.** Retrieve the exact URL from
   the original delivery and verify once with a single `GET`. Do not retype
   tokens or slugs.
5. **Re-issue server-side when the grant is gone.** Create or refresh the
   resource through your authenticated API and mint a fresh signed link;
   replace it everywhere it was shared. Never extend a token client-side.
6. **Tell the customer which case they were in** (expired, unpublished,
   disabled) after you have read the state; do not ask them to retry to find
   out.

## Forged tokens: the 403 vs 404 split, and never retry

The token is an HMAC-signed payload, and any tamper fails a constant-time
compare. Read surfaces report a forged token as the same 404 as an expired
one, because distinguishing them would hand strangers an oracle; some
mutation submits answer `403` instead. Either outcome is terminal for that
token:

* **Do not retry** a 404 or a 403 on a signed surface. The state cannot
  change underneath the request.
* **Do not probe** tokens or slugs to enumerate resources. Scoping is
  per-link; probing only adds load and can trip the public rate limits.
* A burst of 404s on tokens you never issued is expected noise on a public
  surface and is not, by itself, a defect to report.

## What not to do

* **Do not retry the customer's link in a loop** to "see if it comes back".
  Deterministic lookup misses do not.
* **Do not treat `already canceled` or `already submitted` acknowledgements
  as errors.** They are success responses.
* **Do not publish and unpublish an article to probe its state.** Read the
  state in the authenticated console instead.
* **Do not paste API keys or internal ids** into the public link or the
  customer reply.

## Related references

* [Public surface orchestration](https://docs.orbit.devotel.io/guides/public-surface-orchestration.md) — the
  token model, TTLs, and the callback worked sequence.
* [Help center portal](https://docs.orbit.devotel.io/guides/help-center-portal.md) — the publishing gates
  (`ready` + public flag + public category) and the `?org=` slug.
* [Short link not resolving or LINK\_NOT\_FOUND](https://docs.orbit.devotel.io/troubleshooting/short-links-not-resolving.md) —
  the short-link sibling of this family.
* [Error Code Reference](https://docs.orbit.devotel.io/reference/error-codes.md#resources) — the 404 rows
  for this family.
* [Troubleshooting hub](https://docs.orbit.devotel.io/reference/troubleshooting-hub.md) — the runbook index.

## When to contact support

Contact support when your authenticated records show an `ACTIVE` org, an
enabled surface, and a published, public resource, and a single verified
copy of the link still 404s. Include the surface, the tenant-visible
resource id (callback id, article slug, or ticket id), the response's
`meta.request_id`, and the approximate time of the request. Do not include
the signed token itself; it is a bearer grant.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.