Deprecation policy
Learn how Swapcard tells you about API changes, which changes need a deprecation, and how long you have to migrate before a field, query or mutation is removed.
Scope
This policy applies to:
- The Content API (Developer schema). See About the Content API.
- The Analytics API. See About the Analytics API.
It covers any change to the public contract of these APIs: field removals, type changes, behavioral changes, query and mutation removals, and enum value changes.
Principles
- Backward compatible by default. All schema changes are backward compatible. New fields, new optional arguments and new types are non-breaking and can ship at any time.
- No silent removals. A field or query is never removed without going through the full deprecation lifecycle.
- A migration path for every deprecation. Every deprecation includes a concrete alternative or migration instruction.
- Early and repeated communication. You hear about deprecations through several channels and have time to migrate.
Types of change
Non-breaking changes
No deprecation is required for:
- Adding a new field to an existing type
- Adding a new query or mutation
- Adding a new optional argument to an existing query or mutation
- Adding a new enum value
- Adding a new type, union or interface
These changes are documented in the changelog, but don't come with a deprecation notice or a migration period.
Deprecations
These follow the standard deprecation lifecycle:
- Marking a field, query or mutation for future removal
- Replacing a field with a new alternative (for example,
attendees→withEvent.attendees) - Phasing out an enum value
Breaking changes
Breaking changes are only allowed after the full deprecation lifecycle is complete:
- Removing a field, query or mutation
- Changing a field's return type
- Making a nullable field non-nullable (or the reverse, for inputs)
- Changing the meaning of an enum value
- Changing the behavior of a resolver in a way that breaks existing consumers
How changes are announced
Every API change is announced through these channels:
| Channel | When | What |
|---|---|---|
| Changelog | Every release | All changes (additions, deprecations, removals) are listed in the Content API changelog or the Analytics API changelog. |
| At deprecation, then at each reminder | Sent to all mailing list subscribers at each phase of the deprecation lifecycle. | |
| Schema directive | At deprecation | The @deprecated(reason: "...") directive is added to the field in the GraphQL schema, so it shows up in introspection and developer tooling. |
Deprecation lifecycle
The standard deprecation lifecycle lasts 12 months from announcement to removal.
| Phase | Timeline | Technical action | Communication |
|---|---|---|---|
| Announcement | Day 0 | @deprecated directive added to the field with migration instructions. Documented in the changelog. | Email to all mailing list subscribers with the deprecation details and migration guide. |
| First reminder | Month 3 | None. | Reminder email highlighting the upcoming removal and the migration instructions. |
| Second reminder | Month 6 | None. | Reminder email. If usage analytics are available, the email may include usage data to help you assess urgency. |
| End of life | Month 12 | Field, query or mutation removed from the schema. Changelog updated. | Final email confirming the removal, with a link to the migration guide. |
If usage analytics show significant ongoing usage of a deprecated field at Month 6, Swapcard may extend the lifecycle beyond 12 months with additional reminders. Extensions are announced in the changelog and by email.
Emergency deprecation
In exceptional circumstances, a shorter, fast-track deprecation period may apply:
| Reason | Minimum notice | Process |
|---|---|---|
| Security vulnerability | 30 days | Direct outreach to known consumers, email to the mailing list and a changelog entry. Removal after 30 days. |
| Legal or compliance requirement | 30 days | Same as for a security vulnerability. If the legal requirement mandates immediate removal, the field is removed immediately and you are notified afterwards. |
| Critical bug in a deprecated field | 30 days | If a bug is found in an already-deprecated field and fixing it would take significant effort, removal may be brought forward to 30 days, with direct outreach. |
Every emergency deprecation is documented in the changelog with a clear justification.
What every deprecation includes
- Deprecation reason. A clear
@deprecated(reason: "...")message in the schema that explains why the field is being removed. - Alternative. The replacement field, query or approach. For example:
"Use withEvent.attendees instead". - Migration guide. A changelog entry, or a linked document, with before-and-after code examples.
- Timeline. The planned removal date: 12 months after the announcement, unless fast-tracked.
A deprecation message looks like this:
@deprecated(reason: "Use withEvent.attendees instead. Will be removed on 2027-03-01.")
Summary
| Type of change | Deprecation required? | Notice period |
|---|---|---|
| New field, query or mutation | No | None (ships at any time) |
| Field removal or type change | Yes | 12 months |
| Security or legal removal | Yes (fast-track) | 30 days minimum |
| Enum value removal | Yes | 12 months |
| Behavioral change | Yes | 12 months |