Versioning
Note: The Teachify Admin API is currently under development and not yet available for public use. This documentation is provided for preview purposes only.
Overview
Section titled “Overview”The Admin API is versioned by release date. Additive changes (new fields, arguments, types and enum values) ship continuously to every version. Breaking changes are grouped into dated releases that a client opts into.
The field tables in these docs describe the 2027-01-01 release. Timestamps are shown as Int, except fields already documented as BigInt. Under 2027-04-01, those Int timestamps become BigInt strings. See Migrating to 2027-04-01.
Requesting a version
Section titled “Requesting a version”Send the date of the release your integration was built against in the API-Version header:
curl \ -X POST \ -H "Content-Type: application/json" \ -H "X-Teachify-API-Key: <Your API Key>" \ -H "API-Version: 2027-01-01" \ --data '{ "query": "{ courses { nodes { id name } } }" }' \ https://teachify.io/admin/graphqlThe API resolves the header as follows. A credential is the API key, the OAuth application (its creation date, not the access token’s), or the App Installation that authenticates the request.
| Situation | Schema you get |
|---|---|
| Header names a release date | That release |
| Header names a date between two releases | The release in effect on that date |
| Header names a date later than the newest release | The newest release |
| Header names a date older than every release | The baseline (pre-versioning) schema |
| No header, credential created on or after a release date | The release in effect when the credential was created (pinned) |
| No header, credential older than every release | The baseline schema |
| Header present but empty or whitespace-only | Treated as no header |
Header is not YYYY-MM-DD | 400 with extensions.code set to INVALID_API_VERSION |
Any valid YYYY-MM-DD date is accepted, including a future date. To test an upcoming release before it takes effect, send its date now, for example API-Version: 2027-04-01.
The response echoes the version the request was resolved with in an API-Version header: the header value you sent, or the pinned release when you sent none. The response also lists API-Version in Vary. Cross-origin browser clients can read the API-Version response header. A request with no header and no pinned release gets no API-Version response header.
Pinning keeps an integration on the schema it was built against without sending the header. Sending the header on every request is still recommended, and it is required to move to a newer release.
Invalid versions
Section titled “Invalid versions”A header value that is not a YYYY-MM-DD date is rejected with HTTP 400:
{ "errors": [ { "message": "\"latest\" is not a valid API version (expected YYYY-MM-DD)", "extensions": { "code": "INVALID_API_VERSION" } } ]}Deprecation warnings
Section titled “Deprecation warnings”When a request selects a field that a later release removes, the response carries an API-Deprecated header. It names each such field and the release that removes it:
API-Deprecated: CurriculumPlan.symbol; removed=2027-01-01Each entry is Type.field; removed=YYYY-MM-DD. Several entries are separated by commas, and each field appears once. The header is absent when the request selects no field scheduled for removal, and when the request fails validation. Cross-origin browser clients can read the API-Deprecated response header.
Release cadence and support
Section titled “Release cadence and support”- Breaking changes are batched into at most one release per quarter. A release is dated the first day of the quarter:
YYYY-01-01,YYYY-04-01,YYYY-07-01orYYYY-10-01. - A field or type scheduled for removal is marked
@deprecated, with the release date in its reason, at least three months before that date. - Every release stays available for at least twelve months after the next release ships. After that, its definitions may be folded into the baseline. The schedule is announced in the changelog before it happens.
Releases
Section titled “Releases”| Release | Changes |
|---|---|
2027-01-01 | CurriculumPlan.symbol is removed. Use currencySymbol. |
2027-04-01 | Every Unix-timestamp field, argument and filter typed Int / IntOperator moves to BigInt / BigIntOperator, so dates after 2038-01-19 encode. Timestamps already typed BigInt keep their type. See Migrating to 2027-04-01. |
Migrating to 2027-04-01
Section titled “Migrating to 2027-04-01”BigIntis serialized as a JSON string, for example"1893456000". Parse it before you compare or sort it. As strings,"999" > "1000".- Timestamp arguments and filters accept an integer as a JSON number or a numeric string. Any other number is rejected with
must be an integer, including1700000000.0. Values must fall between 0001-01-01 and 9999-12-31 UTC. - Update variable declarations. A
$since: Intor$filter: IntOperatorvariable fails validation against aBigInt/BigIntOperatorargument. Inline literals such assince: 1700000000keep working. If you use code generation, add aBigIntscalar mapping. Generated types change from number to string. - Earlier releases keep
Int. On an earlier release, a timestamp outside theIntrange is clamped to2147483647(2038-01-19) or-2147483648(1901-12-13) instead of failing the query. Do not write a timestamp read on an earlier release back unchanged: it moves a later date to 2038. A clamped value also does not match aneqfilter, and earlier releases cannot send a timestamp after 2038. - On every release, timestamps that were already
BigIntnow get the same integer and 0001–9999 checks. This covers theBigIntOperatorfilters (updatedAton payments, courses and membership plans;createdAton reviews) and the coupon, event, assignment and curriculum plan inputs. A fraction or an out-of-range value is now a validation error instead of a failed request or a silently stored value.