Skip to content

Changelog

All notable changes to the Teachify Admin API are documented on this page.


October 19, 2026

Fixed

  • createCoupon and updateCoupon reject unknown itemIds - An ID in itemIds that is not in the school’s selectable catalog (a typo, another school’s product, a deleted product) used to be dropped silently while the mutation reported success. If every ID was dropped, the coupon applied to every product. The mutation now returns a COUPON-007 message in errors naming the unknown IDs, with coupon set to null, and writes nothing. updateCoupon still accepts IDs the coupon already holds, even after they leave the catalog. An empty array, an omitted field and null keep their meaning.

October 16, 2026

Changed

  • sendCustomEmail escapes HTML in templateVariables - A {{ }} placeholder in content is now filled with its templateVariables value as text: <, >, & and quotes in the value are escaped, so a value forwarded from a member (a name, a form answer) can no longer add links or images to the email. The content itself is still sent as HTML, so put any markup there rather than in a variable. Values already escaped with Liquid’s escape filter are not escaped twice. The subject is plain text and is unchanged.

Fixed

  • sendCustomEmail without templateVariables - Leaving out templateVariables returned success: true but the email was never sent. It is now sent, with each placeholder left empty.

October 15, 2026

Added

  • couponGrants query - Pages through one coupon’s member grants, newest first, filterable by status and by the member’s userId or userEmail. Use it to find the grant ID that revokeCouponGrant takes. It requires coupons:read and students:read.

Changed

  • createCouponGrant argument error codes - Passing neither userId nor email now raises COUPON-005 instead of ENROLLMENT-001, and passing both raises COUPON-006 instead of MEETING-016. Update any error handling that matched the old codes for this mutation; other mutations keep them.

October 1, 2026

Fixed

  • updateSubscription keeps unlimited course access on recurring plans - On a recurring membership plan, a member whose course access had no end date was given one at the new currentPeriodEnd. Renewals never extend that date, so the member lost access while still paying. While the subscription still renews, the mutation now leaves such access without an end date. Course access that already has an end date still moves to currentPeriodEnd. To set a course end date directly, use extendStudentCourseAccess.

September 23, 2026

Added

  • Metadata filters on membership plans and events - membershipPlans and events accept filter: { metadata: [...] }, matching the exact key-value pairs of their external metadata the same way courses does.
  • updatedAt filter on courses and membership plans - courses and membershipPlans accept filter: { updatedAt: { gte: ... } } as a Unix timestamp in seconds through BigIntOperator, which reaches past 2038.

Changed

  • Metadata filters return nothing when the feature is off - A metadata filter on courses, membershipPlans or events for a school without the external metadata feature now returns no results. It previously dropped the filter and returned every course, so a lookup by an ERP key could act on the wrong record.
  • BigIntOperator values must be valid dates - Values outside 0001-01-01 to 9999-12-31 UTC are rejected as invalid input instead of failing the request.

August 30, 2026

Fixed

  • updateSection no longer accepts a null title - Passing title: null previously cleared the section title, which made the affected course unreadable through the storefront API. It now returns SECTION-003. Omit title to leave it unchanged, or pass an empty string for a section with no title.

January 15, 2026

Added

  • Early cancellation for subscriptions pending cancellation - The Admin API cancelSubscription mutation now supports immediate cancellation for subscriptions that are already in a pending-cancellation state (isCanceling: true).
    • cancelAtPeriodEnd and customEndedAt are ignored in this case (always cancels immediately).

Improved

  • Subscription mutation documentation - Updated Admin API docs for subscription mutations with clearer examples and guidance:
    • Early cancellation behavior for cancelSubscription
    • Restrictions for updateSubscription when a subscription is pending cancellation

Fixed

  • Scheduled cancellation behavior - cancelSubscription(cancelAtPeriodEnd: true) now correctly schedules cancellation (subscription becomes isCanceling: true) instead of cancelling immediately.
  • Update restrictions for pending cancellations - updateSubscription now blocks updates for isCanceling: true subscriptions and returns an actionable error directing callers to cancelSubscription.

January 12, 2026

Added

  • Lifetime Membership Plans - Full support for lifetime membership plan type in the API

    • planType: lifetime now available when creating membership plans
    • Lifetime plans have no endAt or currentPeriodEnd dates (perpetual access)
    • Webhooks now include planType field for membership plan events
    • New GraphQL fields:
      • isLifetime on MembershipPlan and Subscription types
      • hasLifetimeAccess on PurchasedCourse type
    • Subscription behavior for lifetime plans:
      • isCancellable: false (one-time purchase)
      • nextChargeDate: null (no recurring charges)
  • Membership Plans Query Filter - New planType filter parameter for membershipPlans query

    • Filter by: recurring, fixed_date, specific_length, lifetime

Improved

  • Subscription Documentation - Enhanced documentation for subscription lifecycle and plan types
    • Added plan types comparison table
    • Clearer explanation of billing cycles and expiration handling

Fixed

  • Payment Reporting - Fixed payment_without_invoices_count to accurately count payments missing issued invoices
  • Subscription Admin - Fixed NoMethodError in admin subscription detail view

January 9, 2025

Added

  • Changelog - This changelog page for tracking API updates

Improved

  • Homepage with clearer navigation and call-to-action

Fixed

  • Broken link to Users query (previously pointed to non-existent Students page)

Removed

  • Internal documentation templates (not intended for external users)

December 20, 2024

Added

  • Lifetime Subscription Support - Permanent access subscriptions with no expiration
    • endAt and currentPeriodEnd return null for lifetime plans
    • isCancellable field to indicate if subscription can be cancelled
  • Invoice Webhook Events - New events for invoice tracking
    • invoice.created
    • invoice.updated

December 6, 2024

Added

  • Student Course Progress Query - Track learner progress through courses
  • Plan Type Filter - Filter membership plans by planType (recurring, fixed_date, specific_length, lifetime)

Improved

  • Subscription documentation with plan types comparison table
  • Course enrollment mutation with plan pricing support

November 15, 2024

Added

  • Rate Limiting Documentation - Clear limits for API usage
    • Mutations: 200 requests per minute
    • Queries: 600 requests per minute
  • Best Practices Guide - Guidelines for effective API usage

October 25, 2024

Added

  • Subscription Mutations - Full subscription lifecycle management
    • Create subscription
    • Update subscription period
    • Cancel subscription (at period end or immediately)
  • Course Access Management
    • Expire student course access
    • Extend student course access

September 15, 2024

Added

  • Initial Admin API Release
    • GraphQL endpoint at https://teachify.io/admin/graphql
    • Authentication via X-Teachify-API-Key header
  • Query Operations
    • Courses, Users, Coupons, Membership Plans, Events, Assignments
  • Mutation Operations
    • Course CRUD, Student enrollment, Post CRUD, Event creation, Custom email
  • Webhook Events - 18 event types across 9 categories
  • Webhook Security - HMAC SHA-256 signature verification, IP allowlisting
  • OAuth 2.0 Integration - Authorization, Token exchange, User info endpoints
  • Zapier Integration - Quickstart guide