Create a Referral via API
Build and submit an outbound co-sell referral to AWS, Microsoft (Azure), or Google Cloud (GCP) directly through the Fours API.
Overview
This page is the developer companion to the Outbound Referral UI walkthrough. It documents the request payload for one endpoint:
POST /org/{orgId}/cosell/referral
- Auth: API key (
Authorizationheader). See Authentication. - Query param:
forceCreate(boolean, optional). Whentrue, the referral is saved in Fours even if it fails validation or the partner rejects it, so you can fix and resubmit later. Defaultfalse. - Response:
200with anOperationExecutionDetailsobject (contains theworkflowIDof the submission). On validation failure you get400with aninfoarray of per-field errors (see Validate first).
One endpoint serves all three clouds. The cloud is chosen by the top-level partner field, and the partner-specific opportunity goes in a matching slot under info. Submission is automatic — the create workflow fires immediately and pushes the referral to the partner. Do not call a sync afterwards for the initial submit. The resulting status is PENDING_CREATE on success or CREATE_FAILED if the partner API rejects it (to resubmit, send the referral back to this endpoint with its id — see Response & next steps).
The envelope
Every request body has the same outer shape, regardless of cloud:
{
"partner": "AWS", // "AWS" | "AZURE" | "GCP"
"salesforceOpportunityId": "0065g...", // optional: link to a CRM opportunity
"salesforceAccountId": "0015g...", // optional: link to the CRM account
"info": {
// exactly one slot, matching `partner` — see table below
},
"metaInfo": { /* optional */ },
"approvalInfo": { /* optional, for the approval workflow */ }
}
The partner-specific opportunity lives in a different info slot for each cloud:
partner | Send the opportunity under | Body type |
|---|---|---|
AWS | info.aceOpportunityV2 | AWS Partner Central opportunity |
AZURE | info.createMicrosoftReferralRequest | Microsoft Partner Center referral |
GCP | info.gcpOpportunityV2 | Google Cloud opportunity |
Two tiers of “required”
Throughout this page, required fields fall into two groups:
- Required by Fours — missing/invalid values return a
400before anything reaches the cloud partner. These are the hard blockers. - Required by the cloud partner — Fours may accept the payload, but AWS/Microsoft/Google will reject it. Fours’ auto-enrich and auto-fix features try to fill some of these; the authoritative list is each cloud’s own API reference, linked per section.
Validate first
Before creating, dry-run the payload against the partner schema:
POST /org/{orgId}/cosell/referral/validate
Send the same envelope you would POST to /referral. A failing response returns the field-level errors so you can correct the payload without creating a CREATE_FAILED record:
{
"code": "BAD_REQUEST",
"message": "failed to validate ...",
"info": [
{ "field": "customer.account.industry", "message": "'Industry vertical' is required" },
{ "field": "relatedEntityIdentifiers.solutions", "message": "'Solutions' is required" }
]
}
AWS
Send the opportunity under info.aceOpportunityV2. Field keys use PascalCase (e.g. Customer, LifeCycle), matching the AWS Partner Central Selling API.
Required by Fours
Field (under info.aceOpportunityV2) | Rule |
|---|---|
Customer.Account.Industry | Non-empty; from the AWS industry list |
Customer.Account.CompanyName | Non-empty (truncated to 120 chars) |
Customer.Account.WebsiteUrl | Valid URL — waived only when NationalSecurity is "Yes" |
Customer.Account.Address.CountryCode | ISO 3166-1 alpha-2 |
Customer.Account.Address.PostalCode | Must match the country’s postal pattern |
Customer.Account.Address.StateOrRegion | Required only when CountryCode is US |
PrimaryNeedsFromAws | Array, at least one value. See AWS field options |
Project.CustomerBusinessProblem | Non-empty, at least 20 characters (over 2000 is truncated) |
RelatedEntityIdentifiers.Solutions | Array of your AWS Solution IDs, at least one. See Where Solution IDs come from |
LifeCycle.TargetCloseDate | YYYY-MM-DD, subject to the close-date policy below |
Conditionally blocked by Fours
These are rejected only when present and invalid. Omit one entirely and Fours’ validator passes — then AWS rejects the submission and the referral lands in CREATE_FAILED. Send them.
| Field | Rule when present |
|---|---|
Project.CustomerUseCase | Must be a valid use-case value |
Project.DeliveryModels | Rejected only if every value is invalid; otherwise invalid entries are dropped |
Project.ExpectedCustomerSpend[0].Amount | Must parse as a number and be >= 0 |
Also required by AWS (Fours does not block these)
Fours’ validator passes without these, but they are flagged requiredForCreation in the AWS ACE schema — AWS rejects the submission without them, so Fours accepts the payload and the AWS step then fails as CREATE_FAILED. The example below includes all of them:
| Field | Notes |
|---|---|
OpportunityType | You provide it: Net New Business | Flat Renewal | Expansion. Silently cleared if invalid, not rejected |
Project.Title | You provide it |
Project.SalesActivities | Fours defaults if omitted |
Origin | You provide it: Partner Referral (the only valid value for Catalog: AWS) |
Marketing.Source | Fours fills (None) |
PartnerOpportunityIdentifier | Fours sets it to the referral ID |
So beyond Fours’ hard-blocked list, the fields you must supply for AWS to accept are Origin, OpportunityType, Project.Title, Project.CustomerUseCase, Project.DeliveryModels, and Project.ExpectedCustomerSpend[0].Amount. The create path runs ValidateAndAIFix, which only repairs fields that are present but invalid within a fixed allowlist — it does not invent missing ones, and Solutions / TargetCloseDate aren’t auto-fixable at all. The authoritative list is the AWS CreateOpportunity reference.
The TargetCloseDate policy
A past close date is not simply rejected. Fours decides per case, so a recently-slipped opportunity still goes through while a stale one is surfaced instead of being quietly laundered into a future date:
LifeCycle.TargetCloseDate | What happens |
|---|---|
| Missing or unparseable | Rejected |
| More than 30 days in the past | Rejected as stale |
| In the past, but within the last 30 days | Auto-pushed forward to today + 30 days |
| Today or in the future | Kept, reformatted to YYYY-MM-DD |
Where Solution IDs come from
AWS has no solution-lookup endpoint (unlike Azure). Your Solution IDs are synced from ACE onto the integration itself — read them from GET /org/{orgId}/integration/AWS/ACE:
info.awsAceIntegration.offeringsV2[]— each entry is{ id, type, title };idis what goes inSolutionsinfo.awsAceIntegration.offerings[]— the older flat array of id strings
The same response carries info.awsAceIntegration.catalog, which tells you whether you are pointed at AWS (production) or Sandbox.
Auto-filled / normalized by Fours
Catalog— set from your connected AWS integration (AWSorSandbox). Don’t send it.Project.ExpectedCustomerSpend[0]— the first entry’sFrequency→Monthly,CurrencyCode→USD,TargetCompany→AWSare always overwritten (AWS only accepts these for this object). You supplyAmount.Marketing.Sourcedefaults to"None";Project.SalesActivitiesdefaults to["Initialized discussions with customer"]when empty or when every value is invalid.NationalSecuritydefaults to"Yes"whenIndustryis"Government"and you left it blank or sent something other than"Yes"/"No". An explicit"No"is preserved.LifeCycle.Stageis cleared if it isn’t a valid stage.Project.CompetitorName,Customer.Account.Duns(9 digits) andCustomer.Account.AwsAccountId(12 digits) are cleared if invalid.Project.AdditionalCommentsandLifeCycle.NextStepsare truncated to 255 characters.OpportunityTeammembers with no usable email are dropped. CustomerContactsare not dropped — an unusable email or phone is just blanked.OpportunityTeam[0]defaults toBusinessTitle: "PartnerAccountManager"andOpportunityTeam[1]to"OpportunityOwner". ThePartnerAccountManageralso gets a default phone number if theirs is missing or unusable.
AWS field options
PrimaryNeedsFromAws — at least one. Any Co-Sell - * value asks AWS for help; Do Not Need Support from AWS Sales Rep files the opportunity without it.
Co-Sell - Architectural Validation · Co-Sell - Business Presentation · Co-Sell - Competitive Information · Co-Sell - Pricing Assistance · Co-Sell - Technical Consultation · Co-Sell - Total Cost of Ownership Evaluation · Co-Sell - Deal Support · Co-Sell - Support for Public Tender / RFx · Do Not Need Support from AWS Sales Rep
OpportunityType — Net New Business · Flat Renewal · Expansion
Project.DeliveryModels — SaaS or PaaS · BYOL or AMI · Managed Services · Professional Services · Resell · Other
Project.SalesActivities — Initialized discussions with customer · Customer has shown interest in solution · Conducted POC / Demo · In evaluation / planning stage · Agreed on solution to Business Problem · Completed Action Plan · Finalized Deployment Need · SOW Signed
LifeCycle.Stage — Prospect · Qualified · Technical Validation · Business Validation · Committed · Launched · Closed Lost
Customer.Account.Industry — Aerospace · Agriculture · Automotive · Computers and Electronics · Consumer Goods · Education · Financial Services · Gaming · Government · Healthcare · Hospitality · Life Sciences · Manufacturing · Marketing and Advertising · Media and Entertainment · Mining · Non-Profit Organization · Energy - Oil and Gas · Other · Energy - Power and Utilities · Professional Services · Real Estate and Construction · Retail · Software and Internet · Telecommunications · Transportation and Logistics · Travel · Wholesale and Distribution
Project.CustomerUseCase — AI Machine Learning and Analytics · Archiving · Big Data: Data Warehouse / Data Integration / ETL / Data Lake / BI · Blockchain · Business Applications: Mainframe Modernization · Business Applications & Contact Center · Business Applications & SAP Production · Centralized Operations Management · Cloud Management Tools · Cloud Management Tools & DevOps with Continuous Integration & Continuous Delivery (CICD) · Configuration, Compliance & Auditing · Connected Services · Containers & Serverless · Content Delivery & Edge Services · Database · Edge Computing / End User Computing · Energy · Enterprise Governance & Controls · Enterprise Resource Planning · Financial Services · Healthcare and Life Sciences · High Performance Computing · Hybrid Application Platform · Industrial Software · IOT · Manufacturing, Supply Chain and Operations · Media & High performance computing (HPC) · Migration / Database Migration · Monitoring, logging and performance · Monitoring & Observability · Networking · Outpost · SAP · Security & Compliance · Storage & Backup · Training · VMC · VMWare · Web development & DevOps
For CountryCode (ISO 3166-1 alpha-2) and the AwsProducts list, see the AWS CreateOpportunity API reference.
Example payload (AWS)
This mirrors the field set the Fours Console submits (the Share with AWS form), so it includes the Fours-required fields, the fields AWS needs to accept the referral, and the common optional fields. It is not the bare validator minimum (see the two lists above). Comments mark // required, // optional, and which fields Fours fills. Treat the AWS reference as the source of truth for what AWS will accept.
{
"partner": "AWS",
"salesforceOpportunityId": "0065g00000XXXXXAAA", // optional: link to the CRM opportunity
"salesforceAccountId": "0015g00000YYYYYAAA", // optional: auto-derived from the opportunity if omitted
"info": {
"aceOpportunityV2": {
"Origin": "Partner Referral", // required (only valid value for Catalog: AWS)
"OpportunityType": "Net New Business", // required: Net New Business | Flat Renewal | Expansion
"NationalSecurity": "No", // optional ("Yes"/"No"); forced "Yes" when Industry = "Government"
"Customer": {
"Account": {
"CompanyName": "Acme Robotics Inc", // required
"Industry": "Software and Internet", // required (valid Industry value)
"WebsiteUrl": "https://www.acmerobotics.com", // required (waived only if NationalSecurity = "Yes")
"Duns": "123456789", // optional (9 digits)
"AwsAccountId": "123456789012", // optional (12 digits)
"Address": {
"CountryCode": "US", // required (ISO 3166-1 alpha-2)
"StateOrRegion": "California", // required when CountryCode = "US"
"City": "San Francisco", // optional
"PostalCode": "94105", // required
"StreetAddress": "123 Market St" // optional
}
},
"Contacts": [ // customer contact(s)
{ "FirstName": "Dana", "LastName": "Cruz", "Email": "[email protected]", "Phone": "+14155550123", "BusinessTitle": "VP Engineering" }
]
},
"PrimaryNeedsFromAws": ["Co-Sell - Deal Support"], // required, >= 1
"Project": {
"Title": "Acme migration to AWS", // required
"CustomerBusinessProblem": "Acme needs to migrate its on-prem fleet platform to AWS to cut latency and scale globally.", // required, 20-2000 chars
"CustomerUseCase": "Migration / Database Migration", // required (valid use-case value)
"DeliveryModels": ["SaaS or PaaS"], // required: SaaS or PaaS | BYOL or AMI | Managed Services | Professional Services | Resell | Other
"SalesActivities": ["Initialized discussions with customer"], // Suger defaults this if omitted
"ExpectedCustomerSpend": [
{ "Amount": "5000" } // required; Suger sets CurrencyCode=USD, Frequency=Monthly, TargetCompany=AWS
],
"CompetitorName": "", // optional
"ApnPrograms": [], // optional
"AdditionalComments": "Joint GTM with the AWS account team." // optional (<= 255 chars)
},
"LifeCycle": {
"TargetCloseDate": "2027-06-30", // required; YYYY-MM-DD — see "The TargetCloseDate policy" above
"NextSteps": "Schedule joint architecture review" // optional (<= 255 chars)
},
"RelatedEntityIdentifiers": {
"Solutions": ["S-0123456"], // required, >= 1 — from GET /org/{orgId}/integration/AWS/ACE
"AwsProducts": ["AmazonBedrock"] // optional (values from the AWS products list)
},
"OpportunityTeam": [ // your team (partner side); members without an email are dropped
{ "FirstName": "Sam", "LastName": "Patel", "Email": "[email protected]", "Phone": "+14155550100", "BusinessTitle": "PartnerAccountManager" },
{ "FirstName": "Jordan", "LastName": "Lee", "Email": "[email protected]", "Phone": "+14155550101", "BusinessTitle": "OpportunityOwner" }
],
"Marketing": { "Source": "None" } // Suger fills "None"; if set to a real source, also provide CampaignName / Channels / UseCases / AwsFundingUsed
}
}
}
CatalogandSoftwareRevenueare intentionally omitted — Fours setsCatalogfrom your AWS integration and controlsSoftwareRevenuebased on your partner program.PartnerOpportunityIdentifieris set to the referral ID for you.
Azure (Microsoft)
Send the opportunity under info.createMicrosoftReferralRequest. Field keys use camelCase.
Required by Fours
Field (under info.createMicrosoftReferralRequest) | Rule |
|---|---|
name | Deal name, non-empty |
details.closingDateTime | UTC datetime (YYYY-MM-DDTHH:MM:SSZ), today or future |
details.dealValue | Number > 0 |
details.currency | ISO 4217 code (defaults to USD if blank) |
customerProfile.address.country | ISO 3166-1 alpha-2 (defaults to US if blank) |
team[] | At least one member, each with email, firstName, lastName, phoneNumber |
details.requirements.solutions[].id | At least one solution (for Private / IPCosell deals) |
details.requirements.additionalRequirements.attributes[] | One SolutionArea and one matching Conversation attribute; plus CustomerMarketplaceIntent for Private/IPCosell. See Field options |
Co-sell vs. independent
A referral is treated as a co-sell (Microsoft is asked to help) when it carries an invitation with organizationId: "msft" and an assistanceRequestCode other than NoHelpRequired. For co-sell referrals you must also provide a customer contact: at least one customerProfile.team[] entry with email, firstName, lastName, phoneNumber (and its email domain must differ from your partner team’s domains).
Fours auto-sets type, status, substatus and dealType, and auto-fixes missing phone numbers.
Field options
dealType
Fours derives this for you — an invitation asking Microsoft for help makes it IPCosell, no invitation makes it Private — so you only need to send it to choose ServicesCosell.
| Value | Label in the console | Requires | Silently removed |
|---|---|---|---|
Private | Private | solutions[], CustomerMarketplaceIntent | PartnerRole |
IPCosell | IP Co-sell | solutions[], CustomerMarketplaceIntent | PartnerRole |
ServicesCosell | Service Co-sell | PartnerRole (solutions[] optional) | CustomerMarketplaceIntent |
assistanceRequestCode
Set on each invitations[] entry. Anything other than NoHelpRequired turns the referral into a co-sell.
| Value | Meaning |
|---|---|
NoHelpRequired | No help required at this point of time |
WorkloadSpecificValueProposition | Workload-specific value proposition |
CustomerTechnicalArchitecture | Customer technical architecture |
ProofOfConceptOrDemo | Proof of concept / Demo |
QuotesOrLicensing | Quotes / Licensing |
PostSalesCustomerSuccess | Post-sales customer success |
GeneralOrOther | General or other |
SolutionArea and Conversation
Send both as entries in details.requirements.additionalRequirements.attributes[], where id is the display string below — not a GUID. Microsoft validates the pair, so a valid conversation under the wrong solution area is rejected.
SolutionArea | Valid Conversation values |
|---|---|
AI Business Solutions | AI-ready productivity and security for every employeeAgentify your business processesAI in the flow of human ambition |
Cloud and AI Platforms | Modernize with confidenceBuild a unified governed data and AI estateAmplify your intelligenceUbiquitous Innovation |
Microsoft Services | Accelerate AI Transformation with Microsoft Services |
Security | AI-ready productivity and security for every employeeEstablish a trusted and secure platform for AI |
Windows and Devices | AI Transformation with Surface and Copilot |
CustomerMarketplaceIntent
Required for Private and IPCosell. If you omit it or send an unrecognized value, Fours defaults it to HaveNotDecided rather than rejecting the referral.
| Value | Label in the console |
|---|---|
Yes | Yes |
No | No |
HaveNotDecided | Have not decided |
PartnerRole
Required for ServicesCosell only, and removed from other deal types.
Adoption and change management · Business strategy · Deployment services · Managed services · Presales envisioning · Proof of concept · Solution design · Transaction
currency and country
details.currency is an ISO 4217 code and customerProfile.address.country is an ISO 3166-1 alpha-2 code, both validated against Microsoft’s picklists. An unrecognized value is not an error — Fours falls back to USD and US respectively. For the full lists see the Microsoft “Create a referral” reference.
Example payload (Azure, independent / no Microsoft help)
This mirrors the field set the Fours Console submits. Comments mark // required / // optional and which fields Fours fills.
{
"partner": "AZURE",
"salesforceOpportunityId": "0065g00000XXXXXAAA", // optional: link to the CRM opportunity
"salesforceAccountId": "0015g00000YYYYYAAA", // optional: auto-derived from the opportunity if omitted
"info": {
"createMicrosoftReferralRequest": {
"name": "Acme – Azure migration", // required (deal name)
"externalReferenceId": "0065g00000XXXXXAAA", // optional: your CRM record id
"team": [ // required: >= 1 partner contact, each with email/firstName/lastName/phoneNumber
{ "firstName": "Sam", "lastName": "Patel", "email": "[email protected]", "phoneNumber": "+14155550100", "title": "Partner Account Manager" }
],
"customerProfile": {
"name": "Acme Robotics Inc", // optional
"address": {
"country": "US", // required (ISO 3166-1 alpha-2; Suger defaults "US")
"city": "San Francisco", // optional
"region": "CA", // optional
"postalCode": "94105" // optional
}
},
"details": {
"closingDateTime": "2027-06-30T23:59:59Z", // required (UTC; today or future)
"currency": "USD", // required (ISO 4217; Suger defaults "USD")
"dealValue": 50000, // required (> 0)
"notes": "Joint migration opportunity.", // optional
"requirements": {
"solutions": [{ "id": "your-solution-id" }], // required (>= 1) for Private / IPCosell deals
"additionalRequirements": {
"attributes": [ // required — see "Field options" above
{ "type": "SolutionArea", "id": "Cloud and AI Platforms" },
{ "type": "Conversation", "id": "Modernize with confidence" },
{ "type": "CustomerMarketplaceIntent", "id": "HaveNotDecided" }
]
}
}
}
}
}
}
Fours sets
type,status,substatus, anddealTypefor you and auto-fixes missing phone numbers — don’t send those.
To request Microsoft co-sell help, add an invitations entry and a customer contact (the customer contact is required once Microsoft help is requested):
"invitations": [
{ "organizationId": "msft", "organizationName": "Microsoft", "assistanceRequestCode": "ProofOfConceptOrDemo" }
],
"customerProfile": {
"address": { "country": "US" },
"team": [ // required for co-sell: >= 1 customer contact
{ "firstName": "Dana", "lastName": "Cruz", "email": "[email protected]", "phoneNumber": "+14155550200" }
]
}
GCP (Google Cloud)
Send the opportunity under info.gcpOpportunityV2. Field keys use camelCase.
GCP has two opportunity types, selected by the top-level opportunityType field:
- Regular —
opportunityTypeisREGULAR(or omitted /TWO_TIER). A standard resell/services opportunity. - ISV Solution Connect —
opportunityTypeisISV_SOLUTION_CONNECT. An ISV solution deal, with its ownisvSolutionConnectInfoblock.
The two types share a customer block but differ in which qualification and product fields are required.
Required for both types
Field (under info.gcpOpportunityV2) | Rule |
|---|---|
opportunityInfo.partnerEntity | Format partners/{id} |
customerInfo.customerDetails.organizationName | Non-empty |
customerInfo.customerDetails.domain | Valid domain |
customerInfo.customerDetails.address.regionCode | ISO 3166-1 alpha-2 |
customerInfo.customerDetails.address.postalCode | Required for most countries (US: 12345 or 12345-6789) |
customerInfo.customerDetails.industry | From the GCP industry list |
customerInfo.customerDetails.employeeCount | Integer > 0 |
customerInfo.contact.givenName, .familyName, .email | All required |
customerInfo.region | One of ANZ, CEE, DACH, FRANCE, INDIA, JAPAN, LATAM_BRAZIL, LATAM_SPANISH_SPEAKING, NE, NORTH_AMERICA, OTHER_ASIA_PACIFIC, SEEMEA, UK_AND_I |
qualificationInfo.contractLengthMonths | Integer 1–96 |
qualificationInfo.estimatedCloseDate | { year, month, day }, future date |
qualificationInfo.dealSize.currencyCode | USD for GCP/Google Maps product categories |
qualificationInfo.dealSize.units | Positive integer as a string, e.g. "50000" |
qualificationInfo.legalLanguageAccepted | Must be true (GCP requirement) |
Required for Regular only
| Field | Rule |
|---|---|
opportunityInfo.productCategory[0] | From the GCP product-category list (e.g. GCP_COMPUTE, GCP_AI, GOOGLE_MAPS) |
qualificationInfo.operationType | NEW, RENEWAL, ADD_ON, EXPANSION |
qualificationInfo.quantity | Integer ≥ 1 |
qualificationInfo.budget | EXACT_BUDGET_GIVEN, BUDGET_EXISTS_NOT_SPECIFIED, CONFIRMED_NO_BUDGET, REFUSE_TO_DISCLOSE |
qualificationInfo.authority | CLEARLY_IDENTIFIED_PROCESS, CONFIRMED_NO_AUTHORITY_DECIDED, VAGUE_UNDERSTANDING, DONT_KNOW |
qualificationInfo.need | CLEAR_NEED, COMPELLING_NEED, NO_NEED |
qualificationInfo.timeline | SPECIFIC_DECISION_DATES_GIVEN, VAGUE_DECISION_DATES_GIVEN, CONFIRMED_NO_DECISION_DATE, REFUSED_TO_GIVE_DATE |
qualificationInfo.decisionPhase | FINAL_DECISION, TRIAL_OR_PILOT, INFORMATION_GATHERING |
Required for ISV Solution Connect only
| Field | Rule |
|---|---|
opportunityInfo.productFamily[0] | GOOGLE_CLOUD_PLATFORM or GOOGLE_WORKSPACE |
opportunityInfo.description | Non-empty |
isvSolutionConnectInfo.contractVehicle | CLOUD_MARKETPLACE, PARTNER_CONTRACT, UNKNOWN |
isvSolutionConnectInfo.deliveryModel | DATA_TO_CUSTOMER_BIGQUERY, VM_ON_CUSTOMER_TENANCY, SAAS_ON_GOOGLE_CLOUD, OTHER_DELIVERY_MODEL |
isvSolutionConnectInfo.supportLevel | TECH, TRANSACTION, UPSELL_RENEW_CROSS_SELL, ALIGN_SALES_ACCOUNT, ALREADY_CONTACT, OTHER_SUPPORT_LEVEL |
For the full industry, productCategory, currency, and region lists, see the Google Cloud opportunities API reference.
Example payload (GCP — Regular)
{
"partner": "GCP",
"salesforceOpportunityId": "0065g00000XXXXXAAA", // optional: link to the CRM opportunity
"salesforceAccountId": "0015g00000YYYYYAAA", // optional: auto-derived from the opportunity if omitted
"info": {
"gcpOpportunityV2": {
"opportunityType": "REGULAR", // REGULAR | TWO_TIER | ISV_SOLUTION_CONNECT
"opportunityInfo": {
"partnerEntity": "partners/123456", // required (partners/{id})
"productCategory": ["GCP_COMPUTE"], // required (>= 1; e.g. GCP_AI, GCP_ANALYTICS, GCP_DATABASES)
"displayName": "Acme Corp – GCP Compute", // optional (auto-generated if omitted)
"confidential": false // optional
},
"customerInfo": {
"customerDetails": {
"organizationName": "Acme Corporation", // required
"domain": "acme.com", // required
"industry": "SOFTWARE", // required (GCP industry value)
"employeeCount": 500, // required (> 0)
"address": { "regionCode": "US", "postalCode": "94043" } // required (regionCode; postalCode for most countries)
},
"contact": {
"givenName": "John", "familyName": "Doe", "email": "[email protected]", // required
"phone": { "e164Number": "+14155550123" } // optional
},
"region": "NORTH_AMERICA" // required (GCP sales region)
},
"qualificationInfo": {
"operationType": "NEW", // required: NEW | RENEWAL | ADD_ON | EXPANSION
"quantity": 1, // required (>= 1)
"contractLengthMonths": 12, // required (1–96)
"dealSize": { "currencyCode": "USD", "units": "50000" }, // required (USD for GCP; units as a string)
"estimatedCloseDate": { "year": 2026, "month": 9, "day": 30 }, // required (future)
"budget": "EXACT_BUDGET_GIVEN", // required
"authority": "CLEARLY_IDENTIFIED_PROCESS", // required
"need": "CLEAR_NEED", // required
"timeline": "SPECIFIC_DECISION_DATES_GIVEN", // required
"decisionPhase": "FINAL_DECISION", // required
"legalLanguageAccepted": true, // required (must be true)
"publicSector": false, // optional
"msspDeal": false // optional
}
}
}
}
Example payload (GCP — ISV Solution Connect)
{
"partner": "GCP",
"salesforceOpportunityId": "0065g00000XXXXXAAA", // optional: link to the CRM opportunity
"salesforceAccountId": "0015g00000YYYYYAAA", // optional: auto-derived from the opportunity if omitted
"info": {
"gcpOpportunityV2": {
"opportunityType": "ISV_SOLUTION_CONNECT", // required for ISV
"opportunityInfo": {
"partnerEntity": "partners/123456", // required (partners/{id})
"productFamily": ["GOOGLE_CLOUD_PLATFORM"], // required for ISV: GOOGLE_CLOUD_PLATFORM | GOOGLE_WORKSPACE
"description": "Deploying our real-time analytics SaaS on GCP for the customer." // required for ISV
},
"customerInfo": {
"customerDetails": {
"organizationName": "TechCorp Inc", // required
"domain": "techcorp.io", // required
"industry": "FINANCIAL_SERVICES", // required
"employeeCount": 2000, // required
"address": { "regionCode": "GB", "postalCode": "SW1A 1AA" } // required
},
"contact": {
"givenName": "Jane", "familyName": "Smith", "email": "[email protected]", // required
"phone": { "e164Number": "+442071234567" } // optional
},
"region": "UK_AND_I" // required (GCP sales region)
},
"qualificationInfo": {
"contractLengthMonths": 24, // required (1–96)
"dealSize": { "currencyCode": "USD", "units": "250000" }, // required
"estimatedCloseDate": { "year": 2026, "month": 6, "day": 30 }, // required (future)
"legalLanguageAccepted": true // required (must be true)
},
"isvSolutionConnectInfo": {
"isvSolutionConnectDeal": true, // required for ISV
"contractVehicle": "CLOUD_MARKETPLACE", // required for ISV
"deliveryModel": "SAAS_ON_GOOGLE_CLOUD", // required for ISV
"supportLevel": "TECH", // required for ISV
"customerContactRequested": false // optional
}
}
}
}
ISV Solution Connect does not require the qualification fields (
operationType,budget,authority,need,timeline,decisionPhase,quantity,productCategory) that a Regular opportunity does — Fours’ validator only enforces those for Regular. Google’s API is the final authority; see the reference linked above.
Response & next steps
A successful create returns OperationExecutionDetails, including a workflowID of the form org/{orgId}/cosell/referral/{referralId}/create — the {referralId} segment is the new referral’s ID.
- The referral lands in
PENDING_CREATEwhile the submission workflow runs, then moves to the partner’s accepted state — orCREATE_FAILEDif the partner API rejects it. To resubmit,GETthe referral, correct it, andPOSTit back to.../cosell/referralwith the sameid— Fours resubmits that referral in place. A body without theidcreates a new referral instead. - Do not call sync for the initial submit — submission is automatic.
- To edit a referral later, use
PATCH /org/{orgId}/cosell/referral/{referralId}. The outbound sync to the partner starts automatically — do not call sync afterwards.
Updating a referral
PATCH /org/{orgId}/cosell/referral/{referralId} edits a referral. By default the partner-specific update validator runs and an outbound sync to the partner is started.
-
Query param:
isLinkageUpdate(boolean, optional, defaultfalse). Whentrue, only the CRM-linkage fields —salesforceOpportunityId,salesforceAccountId,hubspotDealId,dynamics365OpportunityId— are persisted; the partner-opportunity content in the body is ignored, and the update validator and outbound sync are skipped. Sending all four empty unlinks the referral. -
Use it for a pure CRM link or unlink (e.g. attaching a referral to a Salesforce opportunity/account), so the linkage is saved even when the referral’s partner-opportunity state would otherwise fail validation — for example an AWS referral already at the Committed stage. Honored for AWS and GCP; for Azure and Fours the flag is ignored and the normal update path is used.
-
An AWS referral in
CREATE_FAILEDcan’t be edited here. AWS never accepted it, so there is nothing to update: resubmit it instead, by sending it back toPOST .../cosell/referralwith the sameid(see Response & next steps). ThePATCHis refused with400, and the referral is left unchanged:// excerpt of the 400 response "info": [ { "field": "status", "message": "referral <referralId> failed to create (status CREATE_FAILED) and cannot be edited via update; fetch it with GetCosellReferral and resubmit it by calling CreateCosellReferral again with the same id" } ]A linkage-only update (
isLinkageUpdate=true) is not affected.
Partial updates (merge=true, AWS only)
By default a PATCH body replaces the referral’s stored content, so every field has to be sent. Pass merge=true — as a query parameter or in the body — to patch only the fields you send instead. It is supported for AWS only, and the body must always carry "partner": "AWS".
- What merge does with each field. A field you omit keeps its stored value, a field you send replaces it, and an explicit
nullclears it. The exceptions areinfo.aceOpportunityV2.lifeCycle.reviewStatusandlifeCycle.stage: they cannot be cleared, so sending either asnullkeeps its stored value rather than emptying it. - Objects vs. lists. Nested objects merge key by key; lists (such as contacts or solutions) are replaced whole, not merged — send the complete list when you change one entry.
- What is preserved. Merging covers the referral’s top-level fields and
info.aceOpportunityV2. Otherinfosub-documents — for exampleaceEngagementInvitation— are not preserved by an update. - When it is rejected with
400. For a non-AWS partner, when combined withisLinkageUpdate=true, and for an engagement-invitation accept/reject — send the full referral body for those.
The outbound sync to the partner still starts automatically after a merge update; do not call sync afterwards.
Call it from Salesforce (Apex)
If you use the Suger Connector managed package for Salesforce, you can create a referral from Apex without writing your own HTTP callout — call the packaged method with the same payload shape described above (note the Suger. namespace prefix):
Map<String, Object> referral = new Map<String, Object>{
'partner' => 'AWS',
'salesforceOpportunityId' => opp.Id, // optional: link to the CRM opportunity
'salesforceAccountId' => opp.AccountId, // optional: auto-derived from the opportunity if omitted
'info' => new Map<String, Object>{
'aceOpportunityV2' => new Map<String, Object>{
'Origin' => 'Partner Referral', // required
'OpportunityType' => 'Net New Business', // required
'NationalSecurity' => 'No', // optional
'Customer' => new Map<String, Object>{
'Account' => new Map<String, Object>{
'CompanyName' => 'Acme Robotics Inc', // required
'Industry' => 'Software and Internet', // required
'WebsiteUrl' => 'https://www.acmerobotics.com',// required
'Duns' => '123456789', // optional
'AwsAccountId' => '123456789012', // optional
'Address' => new Map<String, Object>{
'CountryCode' => 'US', // required
'StateOrRegion' => 'California', // required for US
'City' => 'San Francisco',
'PostalCode' => '94105', // required
'StreetAddress' => '123 Market St'
}
},
'Contacts' => new List<Object>{
new Map<String, Object>{ 'FirstName' => 'Dana', 'LastName' => 'Cruz', 'Email' => '[email protected]', 'Phone' => '+14155550123', 'BusinessTitle' => 'VP Engineering' }
}
},
'PrimaryNeedsFromAws' => new List<String>{ 'Co-Sell - Deal Support' }, // required
'Project' => new Map<String, Object>{
'Title' => 'Acme migration to AWS', // required
'CustomerBusinessProblem' => 'Acme needs to migrate its on-prem fleet platform to AWS to cut latency and scale globally.', // required
'CustomerUseCase' => 'Migration / Database Migration', // required
'DeliveryModels' => new List<String>{ 'SaaS or PaaS' },// required
'ExpectedCustomerSpend' => new List<Object>{ new Map<String, Object>{ 'Amount' => '5000' } }, // required (Amount)
'SalesActivities' => new List<String>{ 'Initialized discussions with customer' }, // Suger defaults if omitted
'AdditionalComments' => 'Joint GTM with the AWS account team.' // optional
},
'LifeCycle' => new Map<String, Object>{
'TargetCloseDate' => '2027-06-30', // required (future, YYYY-MM-DD)
'NextSteps' => 'Schedule joint architecture review'// optional
},
'RelatedEntityIdentifiers' => new Map<String, Object>{
'Solutions' => new List<String>{ 'S-0123456' }, // required, >= 1
'AwsProducts' => new List<String>{ 'AmazonBedrock' }// optional
},
'OpportunityTeam' => new List<Object>{ // your team (partner side)
new Map<String, Object>{ 'FirstName' => 'Sam', 'LastName' => 'Patel', 'Email' => '[email protected]', 'Phone' => '+14155550100', 'BusinessTitle' => 'PartnerAccountManager' },
new Map<String, Object>{ 'FirstName' => 'Jordan', 'LastName' => 'Lee', 'Email' => '[email protected]', 'Phone' => '+14155550101', 'BusinessTitle' => 'OpportunityOwner' }
},
'Marketing' => new Map<String, Object>{ 'Source' => 'None' } // Suger fills "None"
}
}
};
// forceCreate=false → fail fast on validation errors; true → save even if the partner rejects, to fix & resubmit
Object result = Suger.CosellApi.createCosellReferral(referral, false);
Map<String, Object> operation = (Map<String, Object>) result;
String workflowId = (String) operation.get('workflowID');
- Build
info.aceOpportunityV2/info.createMicrosoftReferralRequest/info.gcpOpportunityV2as nestedMap<String, Object>exactly as the JSON examples above show — the envelope is identical to the REST body. - The method makes an HTTP callout, so it must run in a callout-allowed context: not after DML in the same transaction, and from a record-triggered Flow or trigger it must run asynchronously (Queueable or
@future(callout=true)). - The caller needs co-sell write permission for the partner; the Fours endpoint and authentication are handled by the package.
- To edit a referral, call
Suger.CosellApi.updateCosellReferral(referralId, referralData). For a pure CRM link/unlink (AWS/GCP), callSuger.CosellApi.updateCosellReferralLinkage(referralId, referralData)instead — it sendsisLinkageUpdate=trueso the linkage saves even when the referral’s partner-opportunity state would fail validation (see Updating a referral). updateCosellReferralcalls the samePATCHendpoint, so it is refused for an AWS referral inCREATE_FAILED. To resubmit one, callSuger.CosellApi.createCosellReferralwith the referral including itsid.
From a Flow (no Apex)
You don’t have to write Apex to submit a referral from a Flow. The package ships two invocable actions you can drop straight into Flow Builder:
- Co-Sell (Fire and Forget) — submits and returns immediately (no wait, no Salesforce write-back).
- Co-Sell — submits, waits for the create to finish, then backfills a Salesforce
Referral__crecord.
Each takes three inputs:
| Input | Required | Notes |
|---|---|---|
| Partner | Yes | AWS, AZURE, or GCP. |
| Opportunity ID | No | Builds the payload from a CRM opportunity via field mapping (the original behavior). |
| Referral Payload (JSON) | No | A hand-built payload — the same envelope shown above, as a JSON string. When set, the field-mapping preview is skipped and this payload is submitted as-is. |
Provide one of Opportunity ID or Referral Payload (JSON). If both are set, the payload wins and the Opportunity ID is used only to link the referral to that CRM record.
Because creating a referral is an HTTP callout, place the action on a record-triggered Flow’s Run Asynchronously path (a synchronous after-save path can’t make the callout). Screen and autolaunched Flows can call it directly as long as no DML ran earlier in the transaction.
Listing referrals
GET /org/{orgId}/cosell/referral lists both inbound and outbound referrals, with pagination,
sorting, and a filter expression.
Filter syntax
Pass the filter in q. The default query syntax is lisp, so an expression looks like this:
q=(and (= partner "AWS") (= status "IN_REVIEW"))
The operators below cover the common cases. The filter language accepts more than these — negated forms
such as not_like and not_between, array-membership operators, and dash-spelled aliases like not-in
— so treat this as the working set rather than the complete grammar:
| Category | Operators |
|---|---|
| Comparison | = · != · > · >= · < · <= |
| Set membership | in · not_in |
| Text matching | like · ilike · contains · starts_with · ends_with |
| Null checks | is_null · is_not_null |
| Range | between |
| Combining | and · or · not |
Legal values for status are the Fours unified statuses, in UPPER_SNAKE_CASE: DRAFT,
PENDING_CREATE, CREATE_FAILED, UPDATE_FAILED, IN_REVIEW, PENDING_ACCEPTANCE,
ACTION_REQUIRED, ACTIVE, EXPIRED, CLOSED_WON, CLOSED_LOST, CLOSED_ERROR, and
REJECTED.
Rows the list never returns
Two kinds of row are filtered out server-side, so you cannot retrieve them by asking for them:
| Excluded | Why |
|---|---|
Any referral whose status is DELETED | Deleted referrals are hidden from every list. |
partner=SUGER and status=DRAFT | A Fours partner-to-partner draft is an inbound deal registration still awaiting your review, not a referral yet. It is excluded from this endpoint, from the dashboard, and from the commission ledger. |
The SUGER + DRAFT exclusion is scoped to that exact pair. Azure has its own legitimate
DRAFT flow, and Azure drafts are returned normally.
Full API reference
For the complete request/response schema and to try the endpoint, see Create Co-Sell Referral (POST /org/{orgId}/cosell/referral) in the Fours API reference. The authoritative field definitions for each cloud are the partner references linked above:
Spotted something wrong or out of date on this page? Tell us and we'll correct it.