Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@ yalc.lock
/public/doctree-dev.json

# Claude Code local files
.claude/settings.local.json
.claude/settings.local.json
mise.toml
Empty file.
152 changes: 152 additions & 0 deletions develop-docs/sdk/getting-started/standards/api-architecture.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
title: API and Architecture
sidebar_order: 4
---

## Server-side (Relay) vs. SDK-side decision gate

#### Rule

New processing or transformation logic must default to server-side (Relay).

Logic should only be implemented in the SDK if it must run before data leaves the customer's application (e.g., user-controlled filtering like `before_send_*`), requires access to platform-specific APIs, is strictly latency-sensitive, or must function in offline scenarios.

Transformations of data that has already been collected should be handled in Relay. This ensures consistency across SDK versions and avoids duplicating logic in clients that may remain in use indefinitely.

#### Enforcement

* AGENTS.md instruction
* Human review

#### Suggested skill(s)


#### Per-SDK override

<StatusBadge type="no" /> The default is universal. Justifications are SDK-specific.

---

## SDK-side logic must not break on server changes

#### Rule

SDKs typically outlive individual API versions, so forward compatibility is essential to prevent ecosystem breakage. They must remain resilient to evolving server responses, including additional fields, missing optional fields, new enum values, and rate limiting. They must not fail due to additive changes. Unknown fields, categories, or dimensions should be safely ignored rather than causing errors.

#### Enforcement

* Integration tests for degraded-server scenarios
* Human review

#### Suggested skill(s)


#### Per-SDK override

<StatusBadge type="yes" /> Specific tests vary. Principle is universal.

---

## Public API change approval gate

#### Rule

Any change to public API surface (add, change, deprecate, remove) requires @sdk-leads approval. Public API includes anything a user can call, import, configure, subclass, or otherwise reference. If there is any doubt whether something is public, check for usage in public repositories. When still unsure, treat it as public.

#### Enforcement

* CI API surface snapshot diffs (where feasible)
* Human review gate (senior approval)

#### Suggested skill(s)

* [`sentry-skills:code-review`](https://github.com/getsentry/skills#available-skills) — flags API changes for escalation.

#### Per-SDK override

<StatusBadge type="yes" /> Detection mechanisms are language-specific. Approval requirement is universal.

---

## Semantic conventions process

#### Rule

New attributes must first be defined in [sentry-conventions](https://github.com/getsentry/sentry-conventions).
Process:
1. PR to sentry-conventions
2. code owner approval
3. 3 business day minimum wait
4. SDK implementation

#### Enforcement

* CI validation where feasible
* Human review

#### Suggested skill(s)


#### Per-SDK override

<StatusBadge type="no" />

---

## Breaking change process

#### Rule

Breaking changes must follow the breaking changes playbook.

Breaking changes may only ship in a major version. They must not ship in minor versions. Opt-in previews are allowed in minor versions.

A deprecation period is required in a prior minor version, during which dual behavior is allowed to support migration.

Every breaking change must include:
* A migration guide with copy-pastable examples
* A changelog entry using the BREAKING CHANGE: notation
* Validation of the migration guide using an LLM to ensure it is clear and complete

#### Enforcement

* [Commit footer BREAKING CHANGE:](/engineering-practices/commit-messages/#footer) triggers CI checks
* Breaking changes in non-major branches are CI-blocked
* Human review.

#### Suggested skill(s)

* [`sentry-skills:code-review`](https://github.com/getsentry/skills#available-skills)

#### Per-SDK override

<StatusBadge type="yes" /> Deprecation period timelines can vary. Process is universal.

---

## Deprecation lifecycle

#### Rule

All deprecations of public APIs, user-facing integrations, and supported platforms or frameworks follow three stages:
1. Announce in a minor release with a runtime warning (where possible), updated changelog and documentation, and a migration guide. Warnings must include the replacement, a code example, and a link to the migration docs.
2. Keep the deprecated surface fully functional for at least one subsequent minor release (e.g., deprecated in X.Y, still supported in X.(Y+1)).
3. Remove only in the next major release (X+1.0).

Deprecating an entire SDK must never be silent. It requires clear customer impact analysis, a public announcement, updated documentation, a defined support timeline, and advance EOL notice.

#### Enforcement

* CI checks deprecated APIs still have passing tests
* Human review

#### Suggested skill(s)


#### Per-SDK override

<StatusBadge type="yes" /> Minimum period can be extended. Stages are universal.
14 changes: 14 additions & 0 deletions src/components/statusBadge/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import styles from './style.module.scss';

type StatusType = 'yes' | 'no';

interface StatusBadgeProps {
type: StatusType;
}

export function StatusBadge({type}: StatusBadgeProps) {
const label = type === 'yes' ? 'Yes' : 'No';
const typeClass = type === 'yes' ? styles.yesBadge : styles.noBadge;

return <span className={typeClass}>{label}</span>;
}
26 changes: 26 additions & 0 deletions src/components/statusBadge/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Base badge styles
.yesBadge,
.noBadge {
display: inline-block;
font-weight: 600;
line-height: 1;
white-space: nowrap;
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
border-radius: 0.25rem;
margin-right: 0.5rem;
}

// Yes variant - green
.yesBadge {
background-color: rgb(220, 252, 231);
color: rgb(22, 101, 52);
border: 1px solid rgb(134, 239, 172);
}

// No variant - subtle red
.noBadge {
background-color: rgb(254, 226, 226);
color: rgb(153, 27, 27);
border: 1px solid rgb(252, 165, 165);
}
2 changes: 2 additions & 0 deletions src/mdxComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
SplitSectionCode,
SplitSectionText,
} from './components/splitLayout';
import {StatusBadge} from './components/statusBadge';
import {StepComponent, StepConnector} from './components/stepConnector';
import {TableOfContents} from './components/tableOfContents';
import {VersionRequirement} from './components/version-requirement';
Expand Down Expand Up @@ -118,6 +119,7 @@ export function mdxComponents(
SplitSection,
SplitSectionText,
SplitSectionCode,
StatusBadge,
StepComponent,
StepConnector,
VimeoEmbed,
Expand Down
Loading