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 requireX-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 inYYYY-MM-DDformat.basedOnVersionId(required): theversionIdof the contract version that currently governseffectiveDate. Get it from Read campaign creator contract history. Send an explicit JSONnullonly when that response has an emptyhistoryand bothcurrentandnextScheduledarenull. 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.
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, orHYBRID. It must match the enabled payment sections.currency(required):USD,EUR,GBP,CAD,AUD,CHF,JPY,HKD,NZD,CNY,INR, orSGD.fixedPayment(required): a complete fixed-payment object, ornull.currency: the currency in which the fixed amount is authored.conversionPolicy:nullwhen this matchescontract.currency; otherwise it must beLEGACY_PAYMENT_REPOSITORY_FX.amount: payment amount.per:CREATORorPOST.calculation:STANDARD,PER_POST,SPLIT,PRORATED, orUPLOAD_THRESHOLD.- Also required:
upfrontPercentage,expectedPosts,minimumPosts,prorateByTime,platforms, andcrossposts. Usenull,false, or[]when a field does not apply. upfrontPercentageis non-null only forSPLIT;expectedPostsis non-null only forPRORATED;minimumPostsis non-null only forUPLOAD_THRESHOLD;crosspostsisEACH_POSTorONE_PAYMENT_PER_GROUPonly forPER_POST, and otherwise isnull.prorateByTimecan betrueonly forSTANDARD, andplatformsmust be empty whenperisCREATOR.
cpmPayment(required): a complete view-based payment object, ornull.- Required:
currency,conversionPolicy,rate,perViews,viewsFrom,minimumViews,maximumViews,excludeMinimumViews,maximumSpend,crossposts, andpays. Currency rules are the same as fixed payments. maximumSpendisnullor an object containingamount,per(CREATORorPOST), andperiod(LIFETIME,DAY,WEEK, orMONTH).crosspostsisEACH_POST,BEST_POST, orCOMBINE_POSTS.paysisCAMPAIGN_COMPLETION,NOW, orNOW_AND_STOP.
- Required:
bonusPayment(required): complete bonus rules, ornull.appliesTo:CREATOR,POST, orBEST_POST.pays:CAMPAIGN_COMPLETIONorNOW.rules:VIEWSrules and theirminimum/amounttiers. Every rule also requirescurrencyandconversionPolicyunder the same currency rules.VIEWSis the only supported metric.
crosspostRequirements(required):minimumPlatforms,requiredPlatforms, andcaptionContains, ornull.recurringPayment(required):paymentsPerPeriod,period,weekday,dayOfMonth,startsImmediately,firstPaymentAt, andtimeZone, ornull.- Use
weekdayonly for weekly schedules anddayOfMonthonly for a once-monthly schedule.firstPaymentAtmust benullwhenstartsImmediatelyistrue; otherwise provide an ISO timestamp.
- Use
postsUploadedOnOrAfter(required): aYYYY-MM-DDeligibility date ornull.
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 returns201 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 checksbasedOnVersionId 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:basedOnVersionIdis omitted or invalid; it must be a governing version ID or explicitnullfor an empty timeline400: invalid date, incomplete contract, or unsupported contract terms401: missing or invalid SDK credentials404: campaign creator record not found409 CONTRACT_VERSION_STALE: the governing contract version changed; read history again before retrying409: no existing contract covers the effective date, or the change crosses a protected contract boundary