Skip to main content

POST /sdk/v1/campaign-creators/:campaignCreatorRecordId/contract-history

Adds a contract version that becomes effective for media uploaded on or after the selected date. This is the same contract timeline used throughout Grade. All requests require X-Application-Id and X-Api-Key.

Path parameter

  • campaignCreatorRecordId (required): the campaign creator whose contract you want to update.

Body

  • effectiveDate (required): a real date in YYYY-MM-DD format.
  • basedOnVersionId (required): the versionId of the contract version that currently governs effectiveDate. Get it from Read campaign creator contract history. Send an explicit JSON null only when that response has an empty history and both current and nextScheduled are null. This creates the first contract without guessing that the timeline is still empty.
  • contract (required): the complete contract terms that should apply from that date.
The contract must be complete and explicit. Do not omit fields to imply a default or to inherit an earlier value. Start with the complete contract returned by the history GET, change the intended values, and send every field back. Use null, false, or [] explicitly where shown.
Grade-managed test-phase cutoffs, template identity, and internal history IDs are intentionally not writable through this public shape. Existing values are preserved from the governing unified version; for a first contract, test-phase guards are copied from the creator record. Payment amounts, source currencies, conversion behavior, eligibility dates, grouping, timing, and schedules are all explicit in the request and are never inferred from omitted fields.
To create a creator’s first contract, send the same complete contract shape with "basedOnVersionId": null. The server locks the creator record and rejects the request with 409 CONTRACT_VERSION_STALE if another writer creates a contract first.

Contract fields

  • type (required): NONE, FIXED, PERFORMANCE, BONUS, or HYBRID. It must match the enabled payment sections.
  • currency (required): USD, EUR, GBP, CAD, AUD, CHF, JPY, HKD, NZD, CNY, INR, or SGD.
  • fixedPayment (required): a complete fixed-payment object, or null.
    • currency: the currency in which the fixed amount is authored.
    • conversionPolicy: null when this matches contract.currency; otherwise it must be LEGACY_PAYMENT_REPOSITORY_FX.
    • amount: payment amount.
    • per: CREATOR or POST.
    • calculation: STANDARD, PER_POST, SPLIT, PRORATED, or UPLOAD_THRESHOLD.
    • Also required: upfrontPercentage, expectedPosts, minimumPosts, prorateByTime, platforms, and crossposts. Use null, false, or [] when a field does not apply.
    • upfrontPercentage is non-null only for SPLIT; expectedPosts is non-null only for PRORATED; minimumPosts is non-null only for UPLOAD_THRESHOLD; crossposts is EACH_POST or ONE_PAYMENT_PER_GROUP only for PER_POST, and otherwise is null. prorateByTime can be true only for STANDARD, and platforms must be empty when per is CREATOR.
  • cpmPayment (required): a complete view-based payment object, or null.
    • Required: currency, conversionPolicy, rate, perViews, viewsFrom, minimumViews, maximumViews, excludeMinimumViews, maximumSpend, crossposts, and pays. Currency rules are the same as fixed payments.
    • maximumSpend is null or an object containing amount, per (CREATOR or POST), and period (LIFETIME, DAY, WEEK, or MONTH).
    • crossposts is EACH_POST, BEST_POST, or COMBINE_POSTS. pays is CAMPAIGN_COMPLETION, NOW, or NOW_AND_STOP.
  • bonusPayment (required): complete bonus rules, or null.
    • appliesTo: CREATOR, POST, or BEST_POST.
    • pays: CAMPAIGN_COMPLETION or NOW.
    • rules: VIEWS rules and their minimum/amount tiers. Every rule also requires currency and conversionPolicy under the same currency rules. VIEWS is the only supported metric.
  • crosspostRequirements (required): minimumPlatforms, requiredPlatforms, and captionContains, or null.
  • recurringPayment (required): paymentsPerPeriod, period, weekday, dayOfMonth, startsImmediately, firstPaymentAt, and timeZone, or null.
    • Use weekday only for weekly schedules and dayOfMonth only for a once-monthly schedule. firstPaymentAt must be null when startsImmediately is true; otherwise provide an ISO timestamp.
  • postsUploadedOnOrAfter (required): a YYYY-MM-DD eligibility date or null.

Example request

Bonus tier amounts are totals, not increments. A post with 50,000 views in the example above earns the 10,000-view tier amount of 50.

Response

Successful creation returns 201 with the public contract that was saved.

Safeguards

The endpoint applies the same contract-history safeguards as the Grade app. It will not add a version that changes protected paid or approved work, conflicts with another effective date, bypasses a pending payout approval, or changes a completed campaign where edits are not allowed. The server also checks basedOnVersionId twice: once before validating the contract and again in the transaction that writes it. For a first contract, the explicit null assertion is also checked while the creator record is locked. If the timeline changes between your read and write, the API returns 409 CONTRACT_VERSION_STALE. Writing the same effectiveDate is allowed and replaces that date’s version when basedOnVersionId identifies the existing same-date version and all other safeguards pass.

Common errors

  • 400 CONTRACT_VERSION_REQUIRED: basedOnVersionId is omitted or invalid; it must be a governing version ID or explicit null for an empty timeline
  • 400: invalid date, incomplete contract, or unsupported contract terms
  • 401: missing or invalid SDK credentials
  • 404: campaign creator record not found
  • 409 CONTRACT_VERSION_STALE: the governing contract version changed; read history again before retrying
  • 409: no existing contract covers the effective date, or the change crosses a protected contract boundary
Read the updated timeline with Read campaign creator contract history.