Evaluating Bucker without touching your Sentry setup
You do not have to move to try this. The landing lane pulls your existing error stream into Bucker read-only, from the tool you already run, so the thing being evaluated is Bucker's grouping, essence and remediation loop against your errors rather than against a demo.
Nothing is installed in your application. No SDK changes, no DSN swap, no migration. Your incumbent tool keeps working exactly as it does today, and you can disconnect by deleting one row.
This is a REST surface today. There is no dashboard page for connectors: every call below is
curlor your own script against the control plane. That is the whole gap between this and a finished product feature, and it is stated here rather than discovered halfway through.
1. What lands, and from where
| Provider | Transport | What it reads | Credentials you supply |
|---|---|---|---|
SENTRY |
pull | Issues and their latest event, per project | authToken (read-only) |
DATADOG |
pull | Log events matching your query | apiKey, applicationKey |
CLOUDWATCH |
pull | Log events from a log group | accessKeyId, secretAccessKey, sessionToken |
KAFKA |
push | A topic your pipeline already writes | none — your broker config stays yours |
VECTOR |
push | NDJSON from a Vector http sink, Fluent Bit, Logstash, a shell script |
none — the project's DSN public key |
The live list, with each provider's page size and its dedup behaviour, is served rather than documented:
curl -H "Authorization: Bearer $TOKEN" http://localhost:4000/landing/providers
2. Dual-running does not double-count — for Sentry
This is the part that makes an evaluation trustworthy rather than merely convenient.
SENTRY declares crossOriginDedup: EXACT. A Sentry event's eventID is the 32-hex id
the emitting SDK generated, not an id Sentry minted, so when you fan your existing
SDK out to both products the same underlying error arrives with the same identity from
both directions and Bucker's idempotency on (projectId, eventId) reconciles the two.
You can run both tools side by side for a fortnight and compare counts that mean the
same thing.
DATADOG and CLOUDWATCH declare crossOriginDedup: NONE, and that is published on
the registry rather than hidden: their event ids belong to them, so a record landed from
Datadog and the same error ingested natively are two rows. The connector still dedupes
against itself — landing is idempotent on (connectorId, externalEventId) — so
re-polling costs nothing; it is only the cross-origin reconciliation that cannot be
done, and the landed issue records that it could not.
3. It is polite to your incumbent tool
A connector that gets you rate-limited out of your own dashboard during an incident is an instant uninstall, so the poller is written to stand down first:
- Pages are small on purpose — 25 issues per page for Sentry, against its own cap of 100, and a backfill pass fetches three pages before yielding the process back.
- The upstream cursor is followed verbatim, never rebuilt, so nothing is skipped while upstream keeps writing.
X-Sentry-Rate-Limit-*is read off every response and a pass stops early, with pages left, once the remaining budget drops into the headroom band. Your alerting keeps its share of the quota.- A 401 or 403 stops the connector (
AUTH_FAILED) instead of retrying — that is how an integration gets an account locked out. - A 429 records upstream's own reset instant, persisted, so a restart cannot forget it.
- A backfill stands down when live ingest is behind: both queue depth and the age of the oldest claimable job are read, and either one is enough. A backfill imports at most 50,000 records over a window of at most 90 days.
4. Connect one
# Create the connector.
curl -X POST -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
http://localhost:4000/orgs/$ORG/projects/$PROJECT/landing/connectors \
-d '{
"provider": "SENTRY",
"name": "sentry-prod",
"config": { "organization": "acme", "project": "web", "environment": "production" },
"credentials": { "authToken": "sntrys_..." }
}'
# Prove the credential works before waiting on a schedule.
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:4000/orgs/$ORG/projects/$PROJECT/landing/connectors/$ID/verify
# Pull one page now, rather than waiting for the scheduler.
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:4000/orgs/$ORG/projects/$PROJECT/landing/connectors/$ID/poll
# Import history: a bounded window, cancellable, run in passes.
curl -X POST -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
http://localhost:4000/orgs/$ORG/projects/$PROJECT/landing/connectors/$ID/backfills \
-d '{"windowStart":"2026-08-01T00:00:00Z","windowEnd":"2026-09-01T00:00:00Z"}'
DELETE on the connector is the whole disconnect procedure. The token you gave is
stored encrypted and is never returned by any read route.
For the push transports there is no poller and no credential of ours at all. Vector authenticates with the project's DSN public key — the same trust boundary as ingest and OTLP, through the same resolver — and Kafka authenticates with whatever your own broker config carries in your own process. There is deliberately no field for a broker password: a schema with nowhere to put it is a stronger guarantee than a policy saying we would not store it.
# The DSN goes in a header, not in the URL: a query-string credential ends up in
# every proxy log between your pipeline and us. `?sentry_key=` is accepted for
# sinks that cannot set one.
curl -X POST -H "Authorization: DSN $PROJECT_DSN" \
-H "Content-Type: application/x-ndjson" \
http://localhost:4000/landing/$PROJECT_ID/push \
--data-binary @errors.ndjson
One batch is capped at 500 records, and a sink that sends more is told so rather than silently truncated. A record's identity is your own event id when you send one and a content digest when you do not, so a sink that retries a batch after a timeout lands nothing twice — "your pipeline retried" must not become "the error happened twice" in the counts. The Kafka consumer commits its offset only after landing succeeded; committing first would silently drop a batch on a crash.
5. A landed issue tells you what it is missing
The risk in this lane is not that it fails; it is that it succeeds too convincingly. An issue landed from a foreign product has no repro capsule, frequently no usable in-app frames, no locals, and — unless you also configure a suite — no path to a tier-A verification. If its essence read identically to one built from Bucker's own SDK, every downstream consumer, human and agent alike, would over-trust it.
So every landed issue carries a fidelity block beside its essence, with a closed
vocabulary of twelve gap codes (no_repro_capsule, no_stack_frames, no_in_app_frames,
no_symbolication, no_source_context, no_local_variables, no_breadcrumbs,
no_user_identity, no_release, no_trace_linkage, summary_only, no_suite_config),
one sentence per gap written to be read by a human approver and by an agent, and the
verification tier ceiling those gaps imply:
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:4000/orgs/$ORG/projects/$PROJECT/issues/$ISSUE/landing-fidelity
It is a sibling block rather than an essence field on purpose: the essence schema is a published, frozen contract that other people pin, and adding a field to it would be a major version bump of a specification — see the essence specification.
6. What this does not do
- It is not a migration tool. There is no export of your incumbent's issue state, no comment or assignment import, and no attempt to preserve issue ids.
- It does not raise fidelity. Landing a Sentry issue gives you Bucker's grouping and essence over Sentry's data; it does not give you frames Sentry never captured. To get a tier-A verified fix on an issue, that issue has to arrive through a Bucker SDK with a repro path.
- It has no UI. See the note at the top.
7. When you are ready to move
Point a Bucker SDK at the same project (getting started), leave the connector running, and compare. With Sentry the counts reconcile because the event ids are the same; with the others they do not, and the landed issues say so. When you are satisfied, delete the connector.
Deleting it removes the connector, its backfills, its landed-issue links and its dedup ledger. The issues themselves survive: they are real issues in your project, and "stop reading that upstream" is not "erase what we learned from it". Their origin reconciles back to native the next time anything touches them.