Founding keys are opena year free at 6,000 req/hour, for the first 1,000 developersClaim yours

Try it · no signup, no key

One incident. Four vendors' APIs.

Paste this into a terminal. It follows a single production incident across Slack, Jira, GitHub and GitLab — four different companies' API shapes — and checks that they agree, down to the commit SHA. It takes about ten seconds and asks you for nothing.

four-hop.sh
#!/usr/bin/env bash
#
# One incident, four vendors' APIs, in about ten seconds. No signup, no SDK,
# no key.
#
# WHAT THIS PROVES, and what it deliberately does not claim. Every value
# compared below is pulled from a LIVE response at run time — nothing compared
# here is a literal in this file. Two of the four hops are genuinely
# discovered: the GitHub issue is found by matching Jira's summary text, and
# the GitLab merge request is found by the branch name GitHub just returned.
# The other two are entry points, and are labelled as such.
#
# It is NOT a claim that the providers hyperlink to each other — they don't,
# any more than the real ones do. The claim is simpler and stronger: four
# different vendors' APIs, asked independently, tell one coherent story, and
# they will still agree in a year, because every host below is a frozen
# snapshot pinned to a content hash.
#
# Exits non-zero if any cross-provider check fails, so this is a real
# assertion and not a demo that prints regardless.

set -euo pipefail

command -v curl >/dev/null || { echo "This needs curl." >&2; exit 127; }
command -v python3 >/dev/null || { echo "This needs python3 (used only to read JSON)." >&2; exit 127; }

SLACK=https://slack-2026-08.snap.sandboxapis.dev
JIRA=https://jira-v3-g6.snap.sandboxapis.dev
GH=https://gh-2026-03-g6.snap.sandboxapis.dev
GL=https://gl-v4-g6.snap.sandboxapis.dev

# The three entry points. Overridable so the failure path is testable — a
# demo whose assertions cannot fail is theatre (scripts/four-hop.test.sh).
CHANNEL=${CHANNEL:-CF1UPUMGC8Q}   # the #incident-bridge channel
KEY=${KEY:-FATE-46}               # the tracker key
PR=${PR:-47}                      # the pull request that carried the fix

# Read one value out of a JSON document. python3 is used ONLY as a JSON
# reader — the requests themselves are plain curl, so every URL below is
# something you can paste on its own.
#
# On any failure this reports what the API actually said instead of letting a
# python traceback escape. That matters more here than in most scripts: this
# is the first thing a stranger runs, and a stack trace would read as "the
# product is broken" when the truth is usually "that entry point moved".
#
#   need <what-we-wanted> <json> <python-expression>
#
# `fail` runs inside the command substitution's subshell, so it prints the
# message there and exits non-zero; `set -e` then stops the parent.
need() {
  printf '%s' "$2" | EXPR="$3" python3 -c "
import json, os, sys
try:
    d = json.load(sys.stdin)
    print(eval(os.environ['EXPR']))
except Exception:
    sys.exit(1)
" 2>/dev/null || fail "$1 — the API answered: $(printf '%s' "$2" | tr -d '\n' | cut -c1-160)"
}

if [ -t 1 ]; then
  bold=$(printf '\033[1m'); dim=$(printf '\033[2m')
  green=$(printf '\033[32m'); red=$(printf '\033[31m'); off=$(printf '\033[0m')
else
  bold=""; dim=""; green=""; red=""; off=""
fi

fail() { echo "${red}FAILED: $1${off}" >&2; exit 1; }
ok()   { echo "  ${green}ok${off}  $1"; }
hop()  { echo; echo "${bold}$1${off}"; echo "${dim}  \$ curl -s \"$2\"${off}"; }

# An OPTIONAL key, in the variable the docs already name for one
# (/docs/auth, packages/mcp/README.md). The walk still runs without it — that
# is the whole point of the demo — but it spends five anonymous requests, and
# the anonymous budget is 60/hour PER CALLER across every sandbox host, not per
# host. So a visitor who ran a few `curl` examples from the docs first can
# arrive here with nothing left, which is exactly what happened during the
# 2026-09-13 pre-launch audit.
AUTH=()
if [ -n "${SANDBOXAPIS_API_KEY:-}" ]; then
  AUTH=(-H "Authorization: Bearer $SANDBOXAPIS_API_KEY")
fi

# What an over-limit refusal should say. The API's own 429 is correct and
# provider-shaped — Slack's is `{"ok":false,"error":"ratelimited"}` — but
# provider-shaped means it carries no upsell, so read literally it tells a
# newcomer only that something broke. Every other refusal in this product names
# the rung and the next one; this is the one a NEW visitor is likeliest to
# meet, so it says so here instead.
rate_limited() {
  echo >&2
  echo "${red}Rate-limited (HTTP $1).${off} This walk makes five requests, and anonymous" >&2
  echo "access is 60 requests/hour per caller across every sandbox host — shared" >&2
  echo "with any other example you have run in the last hour. Nothing is broken." >&2
  echo >&2
  echo "  A free key raises it to 600/hour: ${bold}https://sandboxapis.dev/upgrade?from=anonymous${off}" >&2
  echo "  Then re-run with:  ${bold}SANDBOXAPIS_API_KEY=sk_live_… pnpm demo${off}" >&2
  echo >&2
  echo "${dim}  the API said: $(printf '%s' "$2" | tr -d '\n' | cut -c1-160)${off}" >&2
  exit 1
}

# One GET. Sends the key when there is one, and turns an over-limit refusal
# into the message above rather than letting it reach `need` as an unreadable
# body. Everything else is still plain curl, so every URL printed above a hop
# remains something a reader can paste on its own.
get() {
  local raw status
  raw=$(curl -sS ${AUTH[@]+"${AUTH[@]}"} -w $'\n%{http_code}' "$1")
  status=${raw##*$'\n'}
  case "$status" in
    403|429) rate_limited "$status" "${raw%$'\n'*}" ;;
  esac
  printf '%s' "${raw%$'\n'*}"
}

echo "${bold}One incident, four vendors' APIs.${off}"
echo "${dim}Every value below is read from a live response.${off}"

# --- 1. Slack: the conversation --------------------------------------------
URL="$SLACK/api/conversations.history?channel=$CHANNEL&limit=1"
hop "1 - Slack: the argument" "$URL"
SLACK_JSON=$(get "$URL")
TEXT=$(need "no message in #$CHANNEL" "$SLACK_JSON" "d['messages'][0]['text']")
TS=$(need "no timestamp on that message" "$SLACK_JSON" "d['messages'][0]['ts']")
SLACK_AT=$(TS="$TS" python3 -c "import datetime,os;print(datetime.datetime.utcfromtimestamp(float(os.environ['TS'])).strftime('%Y-%m-%dT%H:%M:%SZ'))")
ok "$SLACK_AT - \"$TEXT\""

# The distinctive phrase, taken from what Slack just said rather than typed
# here. Values reach python through the ENVIRONMENT, never spliced into its
# source: the opening message contains an apostrophe, and quoting user data
# into a program is fragile and the wrong habit besides.
PHRASE=$(TEXT="$TEXT" python3 -c "import os;print(os.environ['TEXT'].split('.')[0].strip())")

# --- 2. Jira: the same incident as a ticket ---------------------------------
URL="$JIRA/rest/api/3/issue/$KEY"
hop "2 - Jira: the ticket" "$URL"
JIRA_JSON=$(get "$URL")
SUMMARY=$(need "no such issue as $KEY" "$JIRA_JSON" "d['fields']['summary']")
CREATED=$(need "$KEY has no created date" "$JIRA_JSON" "d['fields']['created']")
ok "$KEY - \"$SUMMARY\""

PHRASE="$PHRASE" SUMMARY="$SUMMARY" python3 -c \
  "import os,sys;sys.exit(0 if os.environ['PHRASE'].lower() in os.environ['SUMMARY'].lower() else 1)" \
  || fail "Slack's phrase is absent from Jira's summary - the two vendors disagree."
ok "Jira's summary carries Slack's exact words ${dim}(two vendors, one incident)${off}"

GAP=$(CREATED="$CREATED" TS="$TS" python3 -c "
import datetime, os
c = datetime.datetime.strptime(os.environ['CREATED'][:19], '%Y-%m-%dT%H:%M:%S')
s = datetime.datetime.utcfromtimestamp(float(os.environ['TS']))
print(int((s - c).total_seconds() // 60))
")
[ "$GAP" -gt 0 ] || fail "The thread opens before the ticket was filed - chronology is broken."
ok "Filed $GAP minutes before the thread opened ${dim}(chronology holds across vendors)${off}"

# --- 3. GitHub: the issue, DISCOVERED from Jira's words ---------------------
URL="$GH/repos/olympus-labs/parthenon/issues?state=all&per_page=100"
hop "3 - GitHub: the same issue, found using Jira's text" "$URL"
ISSUE_NUM=$(get "$URL" | SUMMARY="$SUMMARY" python3 -c "
import json, os, sys
want = os.environ['SUMMARY'].strip().lower()
for i in json.load(sys.stdin):
    if i.get('title', '').strip().lower() == want:
        print(i['number']); break
")
[ -n "$ISSUE_NUM" ] || fail "No GitHub issue carries Jira's summary."
ok "issue #$ISSUE_NUM - same title, discovered by searching on Jira's text"

# --- 4. GitHub: the pull request that fixed it ------------------------------
URL="$GH/repos/olympus-labs/parthenon/pulls/$PR"
hop "4 - GitHub: the pull request" "$URL"
PR_JSON=$(get "$URL")
BRANCH=$(need "no such pull request as #$PR" "$PR_JSON" "d['head']['ref']")
GH_SHA=$(need "PR #$PR has no head SHA" "$PR_JSON" "d['head']['sha']")
MERGED=$(need "PR #$PR has no merged flag" "$PR_JSON" "str(d['merged']).lower()")
[ "$MERGED" = "true" ] || fail "PR #$PR is not merged - the story does not close."
ok "PR #$PR merged ${bold}$BRANCH${off}"
ok "head SHA ${bold}$(printf '%.12s' "$GH_SHA")${off}"

# --- 5. GitLab: the same branch, DISCOVERED on another vendor ---------------
URL="$GL/api/v4/projects/olympus-labs%2Fparthenon/merge_requests?source_branch=$BRANCH"
hop "5 - GitLab: the same branch, on a different vendor" "$URL"
GL_JSON=$(get "$URL")
MR_IID=$(need "no GitLab MR for branch $BRANCH" "$GL_JSON" "d[0]['iid']")
GL_SHA=$(need "that MR has no head SHA" "$GL_JSON" "d[0]['sha']")
ok "MR !$MR_IID - found by the branch name GitHub just returned"

[ "$GH_SHA" = "$GL_SHA" ] || fail "SHAs differ: GitHub $GH_SHA vs GitLab $GL_SHA"
ok "head SHA $(printf '%.12s' "$GL_SHA") - ${green}identical to GitHub's${off}"

# --- what just happened ------------------------------------------------------
echo
echo "${bold}Four vendors. One story. No setup.${off}"
echo
echo "  Slack     the argument, at $SLACK_AT"
echo "  Jira      $KEY, filed $GAP minutes earlier"
echo "  GitHub    issue #$ISSUE_NUM, found using Jira's own words"
echo "  GitHub    PR #$PR merged $BRANCH"
echo "  GitLab    MR !$MR_IID - same branch, same SHA $(printf '%.12s' "$GH_SHA")"
echo
echo "Nothing was seeded by you, and the two cross-vendor hops were discovered,"
echo "not hardcoded: the GitHub issue was found using text Jira returned, and the"
echo "GitLab merge request was found using the branch GitHub returned."
echo
echo "Every host above is a frozen snapshot pinned to a content hash, so this"
echo "script returns these same bytes in a year. That is what CI needs and what"
echo "a live provider cannot give you."
echo
echo "  ${dim}Point your own client at it:${off}  https://sandboxapis.dev/docs"
echo "  ${dim}What's covered, honestly:${off}     https://sandboxapis.dev/coverage"

Needs only curl and python3, and python is used purely to read JSON — every request is a plain curl you can paste on its own.

What comes back

output
1 - Slack: the argument
  ok  2026-06-14T16:46:48Z - "schema marks a nullable field as required. paging
      whoever's closest to the logger."

2 - Jira: the ticket
  ok  FATE-46 - "Postmortem follow-up: schema marks a nullable field as required"
  ok  Jira's summary carries Slack's exact words (two vendors, one incident)
  ok  Filed 8 minutes before the thread opened (chronology holds across vendors)

3 - GitHub: the same issue, found using Jira's text
  ok  issue #46 - same title, discovered by searching on Jira's text

4 - GitHub: the pull request
  ok  PR #47 merged clio/leak-http-client-keep-alive-pool
  ok  head SHA d2aa02c65f19

5 - GitLab: the same branch, on a different vendor
  ok  MR !13 - found by the branch name GitHub just returned
  ok  head SHA d2aa02c65f19 - identical to GitHub's

The walk

  1. Slackslack-2026-08.snapAn engineer opens a thread at 16:46:48Z — “schema marks a nullable field as required.”
  2. Jirajira-v3-g6.snapFATE-46 was filed eight minutes earlier, carrying that same sentence in its summary.
  3. GitHubgh-2026-03-g6.snapIssue #46 has the identical title — found by searching on the text Jira returned, not by a link.
  4. GitHubgh-2026-03-g6.snapPR #47 merged clio/leak-http-client-keep-alive-pool at d2aa02c65f19.
  5. GitLabgl-v4-g6.snapMR !13 — found by that branch name, on a different vendor, reporting the same SHA.

What this proves — and what it doesn't

Nothing here is hardcoded

Every value the script compares is read from a live response. Two of the hops are genuinely discovered rather than given: the GitHub issue is found by searching on the summary text Jira returned, and the GitLab merge request is found by the branch name GitHub returned. Change a value on one vendor and the script exits non-zero.

It is not a claim of hyperlinks

These providers don't cross-reference each other, any more than the real ones do. The claim is simpler: four vendors' APIs, asked independently, tell one coherent story — because it is one simulated company underneath, not four sets of fixtures someone kept in sync by hand.

It will say this in a year

Every host above is a frozen snapshot pinned to a content hash. Re-run this next year and the bytes are identical — which is what CI needs and what pointing your tests at a live provider can never give you. How pinning works.

Now point your own client at it

The same universe answers Octokit, python-gitlab, jira.js and the rest — the only change is the base URL. Nothing above required a key, and reads stay open without one. Start with the quickstart.

Read the quickstart Tour the whole universe