Easy2257

Changelog

Partner API version history.

v2026-09-05

Solo accounts

  • New: POST /api/v1/solo-accounts/{accountId}/deactivate and POST .../reactivate. A platform that funds its creators can now take a creator off its roster and bring them back. Deactivating suspends the account with suspendReason: partner_deactivated, fires solo_account.suspended with that reason, and takes the creator off your next invoice; their records stay in custody. Reactivating clears only that suspension, runs no new verification, and fires solo_account.verified again when the creator's ID is on file. Both are idempotent. Only creators your platform funds: a creator who subscribes directly returns 409 CREATOR_PAYS_OWN_SUBSCRIPTION. The same two actions are on the portal roster at partner.easy2257.com.
  • suspendReason is now documented. The values are subscription_lapsed, platform_lapsed, partner_deactivated, platform_deactivated and manual_suspension; the solo_account.suspended event reference says what each means and what clears it. The previous example value subscription_payment_failed was never emitted.

v2026-08-22

Certificates

  • production.documented now fires again when a producer reissues a sealed package. A producer who corrects a closed record can rebuild the sealed package themselves. Easy2257 re-mints the certificate and sends the same production.documented event, with the payload shape you already handle. Treat the newest delivery for a productionId as the certificate that stands. The one it replaces is marked SUPERSEDED, not revoked: the content stays up and nothing lands in GET /api/v1/productions/revoked-certificates. Handlers that store the certificate keyed on productionId and overwrite need no change; handlers that ignore a repeat delivery will hold a superseded certificate.

Archives

  • A production's sealed package can change after it is first sealed. When a producer corrects a closed record and reissues, the archive is rebuilt and its zipSha256 and reportPdfSha256 change, along with the sealed date. A package downloaded before the reissue still exists and is still kept; it is superseded rather than invalid. Compare hashes against the package that stands today rather than against one you cached.

v2026-08-15

Certificates

  • Annual renewal no longer revokes the outgoing certificate — it supersedes it. A renewal now stamps the old certificate SUPERSEDED instead of revoked, so revocation means exactly one thing: the certified record was pulled and the content comes down. POST /{productionId}/verify-certificate returns the new reason certificate_superseded for a renewed-away certificate; handlers treating every valid: false as a takedown should branch on the reason — a superseded certificate means swap in the replacement, the content stays up.
  • The revocation list carries revocations only. New renewals no longer appear in GET /api/v1/productions/revoked-certificates. Each entry gains a type field (revocation or supersession); supersession appears only on entries recorded before this change and their content stays up. Handlers that skipped annual_renewal entries keep working unchanged.
  • Certificates are now stored and retrievable. New endpoint GET /api/v1/productions/{productionId}/certificates lists every certificate for a linked production, newest first, with lifecycle status (CURRENT, SUPERSEDED, REVOKED) and the signed JWT. Certificates issued before this change return jwt: null; those arrive with the next annual renewal. Missing a production.documented webhook is no longer unrecoverable.

v2026-08-14

Collab scenes (breaking)

  • POST /{sceneId}/extend no longer returns performer emails. The performers array is removed from the 200 body and replaced by three counts: performerCount, consentedCount, releaseSignedCount. The extending partner is not the scene owner, and the consent and release state those counts summarize is all the extension flow needs; the roster's email addresses belong to the scene owner's records. sceneId, status, extendedTo, fee, and nextStep are unchanged. Handlers reading performers must switch to the counts.

Rate limits

  • /api/v1 requests with a Bearer key are now limited per key, not per IP: 300 requests per 60 seconds. Your budget is no longer drawn down by other services behind your NAT address or by other traffic from your egress IP, and it is five times larger. Requests without a key keep the previous per-IP limit of 60 per 60 seconds, and a per-address flood ceiling of 1200 per 60 seconds bounds keyed traffic during abuse. The X-RateLimit-* headers and the 429 body are unchanged in shape.

Webhooks

  • X-EZ2257-Delivery now carries the full delivery id. The value keeps its del_ prefix and stays an opaque identifier; it is simply longer. The previous shortened form could repeat across two deliveries created in the same instant. If you deduplicate, keep keying on event.id, which is unchanged.

v2026-07-27

Security and correctness release. Several of these changes are breaking for existing integrations. Read the two Breaking sections before your next deploy.

Breaking

  • Test-mode keys are rejected. There is no sandbox. Any ez_test_ key now returns 403 with code TEST_MODE_UNAVAILABLE on every /api/v1/* endpoint, before the handler runs. Only ez_live_ keys work. The rejection is recorded in your API usage log. Previously test keys wrote production records, provisioned real users, and sent real email, which is why they are now blocked outright.
  • The password-claim endpoint on /api/partner-onboard/{token} is gone. A partner-held token that could set a password was a partner-held password. Creators set their own password through the ordinary forgot-password flow, which the provisioning email already links them to. Remove any call to it: there is nothing to replace it with, and the onboarding flow no longer needs one.
  • Cross-partner reads return 404, not 403. Requesting an accountId that belongs to another partner now returns 404 with Solo account not found, identical to an id that does not exist, so the API cannot be used to enumerate accounts. Handlers that branched on 403 for this case must branch on 404.

Collab scenes (breaking)

  • POST /api/v1/collab-scenes now identifies the uploader by uploaderAccountId or uploaderExternalUserId (exactly one). These are the two values a partner already holds: the accountId Easy2257 issued at provisioning, or the externalUserId you supplied there. Either must resolve to an active solo account under your partner account. The documented uploaderUserId field asked for an Easy2257 user id, a value no endpoint has ever returned to a partner; it remains accepted for Easy2257-internal callers only.
  • POST /{sceneId}/extend takes no request body. Authorization is possession of the sceneId of a greenlit scene, the id the scene's creating partner shares with you when the syndication is arranged. The former uploaderUserId body field and the 403 uploader_mismatch rejection are gone.
  • /extend reports its charge and retries safely. The response gains a fee object (extensionFeeCents, charged, stripeChargeId, chargeError). Extensions are recorded at most once per partner per scene: a re-POST retries an unpaid fee instead of charging twice, and a failed charge does not revoke the extension.
  • preEnrolled is removed from performer entries, and pending_registration is no longer emitted. Both revealed whether an arbitrary email already had an Easy2257 account, which contradicted the anti-enumeration guarantee everywhere else in the API. Every invited performer now reports pending_consent until they sign (consented) or decline (refused). Handlers reading preEnrolled or matching pending_registration must drop those branches.
  • Scene creation responses carry fees.chargeError: null when the immediate off-session charge succeeded, otherwise a failure code such as no_payment_method or card_declined. The scene is created and consent collection proceeds either way.

When you provision an email that already belongs to an Easy2257 user, that user is emailed and asked to approve the connection before their identity record is linked to your platform.

  • POST and DELETE on /api/v1/solo-accounts/{id}/content return 409 with code CONSENT_PENDING (asked, not yet answered) or CONSENT_DECLINED (refused). Treat both as "creator not ready to publish".
  • The provisioning response itself is unchanged and deliberately identical to a fresh signup, so no code change is required at step 1 and your integration cannot be used to probe whether an address already has an Easy2257 account.
  • The approval email is throttled to at most one per creator per day, and a creator who declines is never emailed about your platform again.

Status values a partner can observe

GET /api/v1/solo-accounts/{id} returns exactly four values: pending_id_verification, subscribed_pending_id, active, suspended. Internal states (pending_consent, consent_declined, id_verified) are collapsed into pending_id_verification so account existence and consent decisions are not observable. Unlock uploads on active only.

Note that the solo_account.verified webhook carries status: "verified", not "active". Match on event.type.

Revoked certificates: cursor and reason semantics

  • The response timestamp field is retrievedAt. Pass it as since on your next sync.
  • nextCursor is an opaque token. Pass it back verbatim as cursor. It is not a productionId.
  • Ordering is stable by (revokedAt, certificate id), so pages never skip or repeat.
  • The reason for an actioned takedown is removal_request:<id>, a prefixed variable value. Match on the removal_request: prefix. The other values are annual_renewal and unspecified.

Webhooks

  • Documented the full event list. In addition to the solo-account and content-log events, Easy2257 delivers collab_scene.created, .performer_consented, .performer_refused, .greenlit, .blocked, .cancelled, .publication_created, .publication_removed, upload_session.solo_completed, performer.id_verified, performer.forms_signed, verification.cancelled, the four production.* events, and test.ping.
  • Documented the X-EZ2257-Event and X-EZ2257-Delivery headers, which ship on every delivery.
  • Clarified that retries are re-signed with a fresh timestamp, so deduplication must key on event.id.
  • Clarified that endpoints are registered in the partner portal. The callbackUrl field on a resource never subscribed you to events.

Partner dashboard

The partner dashboard now lives at partner.easy2257.com. Old /profile/partner/* paths permanently redirect there. API keys are at /api-keys, webhook endpoints and delivery history at /webhooks, request logs at /api-usage.

Endpoints that were live but unlisted

These are not new. They were missing from this changelog, and one of them was wrongly listed as "coming soon" while it was already shipped.

  • DELETE /api/v1/solo-accounts/{id}/content/{externalContentId}: remove a logged depiction
  • POST /api/v1/collab-scenes/{id}/publications/{pubId}/remove: record a takedown of a syndicated publication
  • POST /api/v1/upload-sessions: start a hosted attestation session

The previous "Coming soon" list has been removed. A content-log list endpoint, a hashed-email lookup endpoint, and language SDKs were listed there and none of them exist or are in progress. The hashed-email lookup in particular would have undone the one privacy control on the takedown webhook, so it is not planned.

v2026-04-25

Productions (Verification API): new

  • GET /api/v1/productions/{id}: fetch production documentation status
  • GET /api/v1/productions?performerEmail=: list productions a performer appears in (VIRP right-to-removal lookup)
  • POST /api/v1/productions/{id}/verify-certificate: validate a stored compliance certificate
  • GET /api/v1/productions/revoked-certificates: daily revocation sync
  • GET /.well-known/jwks.json: public JWKS for offline RS256 certificate verification

New webhook events

  • production.documented: fires when a producer completes documentation (payload includes the issued JWT)
  • production.takedown_requested: fires when a depicted person submits a removal request
  • production.certificate_renewed: fires on annual certificate renewal
  • production.records_inspected: fires when a federal inspector accesses records

v2026-04-22: Initial public release

Solo Accounts

  • POST /api/v1/solo-accounts: provision solo creator account
  • GET /api/v1/solo-accounts/{id}: get account status
  • POST /api/v1/solo-accounts/{id}/content: log a content depiction

Talent

  • POST /api/v1/talent/check: look up prior verification status by email

Collab Scenes (multi-performer)

  • POST /api/v1/collab-scenes: create a collab scene with magic-link consent flow
  • GET /api/v1/collab-scenes/{id}: fetch scene status and performer progress
  • POST /api/v1/collab-scenes/{id}/cancel: cancel a pending scene
  • POST /api/v1/collab-scenes/{id}/extend: publish to another partner platform without re-collecting signatures
  • POST /api/v1/collab-scenes/{id}/publications: register a published content URL

Webhooks

  • solo_account.verified, solo_account.suspended
  • collab_scene.greenlit, collab_scene.blocked, collab_scene.publication_removed
  • content_log.created, content_log.deleted

On this page