# Fours Documentation > Fours is a cloud go-to-market platform for selling and billing software through cloud marketplaces (AWS, Microsoft, Google Cloud, Snowflake, Alibaba Cloud, Oracle), with metering, invoicing, revenue reporting, CRM/PRM integrations, and workflow automation. ## Instructions for LLM agents - Every documentation page is available as clean markdown by appending `.md` to its URL (for example https://doc.fours.com/get-started/account.md). Read and cite these `.md` URLs. - Each public API operation has a markdown page at https://doc.fours.com/api/.md (for example https://doc.fours.com/api/create-offer.md); the overview — authentication, conventions, and every operation by group — is at https://doc.fours.com/api/. - To take actions against the Fours API rather than only read docs, Fours hosts an MCP server at https://apiv2.suger.cloud/mcp whose tools map to the same public API operations documented here. - The public API base URL is https://api.suger.cloud. - Fours was formerly named Suger. These docs are at doc.fours.com (the old doc.suger.io address 301-redirects here), and product identifiers still carry the old name — the console at console.suger.io, the API hosts on suger.cloud, `SUGER_`-prefixed variables, and `suger`-prefixed fields. Use them exactly as written. - Fours Insulin, the AI platform documented under https://doc.fours.com/insulin/, has its own product site with its overview and pricing: https://www.insulin.dev/. - Rely only on the operations and flows described in these docs; some older marketplace, offer, and entitlement endpoints have been removed. --- Source: https://doc.fours.com/get-started/quick-start/ # Quick Start New to Fours? This is the shortest path from signing up to seeing your first offer in the console. The hands-on work adds up to roughly **30 minutes**, but two things are outside your control: Fours has to approve your organization before anything else can start, and publishing a *new* marketplace listing adds weeks of cloud-provider review. Follow the checklist top to bottom; each step links to the full guide. --- ## Hands-on time vs. waiting **Hands-on** is work you do in the console. **Waiting** is out of your hands — start the gated steps early and run the rest in parallel. | # | Step | Who does it | Hands-on | Then you wait | |---|------|-------------|----------|---------------| | 1–2 | Create your account and organization, then get it approved | You, then Fours Support | ~10 min | Usually within 1 business day, up to 2 | | 3 | Connect your first cloud marketplace | You, with a cloud admin | ~20 min | — | | 4 | Add your first product | You | ~1–2 hrs to build a new listing; minutes to import an existing one | **New listing:** ~2 weeks (AWS, Azure) or ~3 weeks (GCP) of provider review. **Importing an existing listing:** ~5 days to update fulfillment URLs | | 5 | Create your first offer | You | Minutes | Publishing takes up to 15 minutes; GCP SaaS offers also need a manual approval unless you have enabled automatic offer approval | | 6 | Track it in the console | You | — | — | :::info Step 4 is the only one where "30 minutes" of hands-on work stops applying, and only if you are publishing a brand new listing. If you are already live on a marketplace and importing that listing, the whole path really is about half an hour of work plus the waits. Step 5 always adds a short publishing wait — and a manual approval on GCP SaaS offers — but no extra hands-on time. For full per-cloud numbers see [Integration Timeline](/get-started/integration-timeline/). ::: ## The path from signup to your first offer ```d2 grid-columns: 3 grid-gap: 70 classes: { step: { width: 225; style.border-radius: 8 } } setup: "Get set up" { style.border-radius: 14 a: "1 · Create your account\n& organization" { class: step } b: "2 · Get your organization\napproved" { class: step } a -> b } sell: "Connect & sell" { style.border-radius: 14 c: "3 · Connect your first\ncloud marketplace" { class: step } d: "4 · Add your first\nproduct" { class: step } e: "5 · Create your first\noffer" { class: step } c -> d -> e } golive: "Go live" { style.border-radius: 14 f: "6 · Track it in\nthe console" { class: step } } setup -> sell -> golive ``` ### 1. Create your account and organization Sign up, turn on multi-factor authentication, and create your organization. Everyone on your team works inside one organization. → [Account](/get-started/account/) ### 2. Get your organization approved :::warning A brand-new organization stays **inactive** until Fours approves it. Email [support@suger.io](mailto:support@suger.io) — or post in your shared Slack channel if you have one — to request activation. You won't be able to connect a marketplace or create offers until this is done. Approval usually lands **within 1 business day**, and can take up to 2. Request it before you do anything else, and follow up if you haven't heard back by then. ::: ### 3. Connect your first cloud marketplace Link the cloud marketplace you sell through (AWS, Azure, GCP, and more). This is the real first setup task, and it unlocks products, offers, and billing. → [Connect your first cloud marketplace](/get-started/connect-your-marketplace/) ### 4. Add your first product A **product** is your marketplace listing. Importing a listing you have already published takes minutes. Building and submitting a **new** listing takes about 1–2 hours of your time, and then the cloud provider reviews it — roughly 2 weeks on AWS and Azure, 3 weeks on GCP. Don't tie a deal date to that review. → [Products](/console/products/) · [Integration Timeline](/get-started/integration-timeline/) ### 5. Create your first offer An **offer** is how a buyer purchases your product — a self-serve public offer or a negotiated **private offer**. Create a private offer to make your first deal. → [Private Offers](/console/private-offers/) · [Direct Sales with Fours](/concepts/direct-sales/) ### 6. Track it in the console Watch the deal, revenue, and time-sensitive tasks from the Home dashboard, and learn where everything lives. → [Home Dashboard](/console/home-dashboard/) · [Navigate the Fours Console](/get-started/navigate-console/) --- ## Track your progress from your own tools The six steps above are also readable over the API, so you can drive an internal dashboard or a rollout checklist from the same state Fours uses. `GET /org/{orgId}/onboarding/status` returns the steps in a fixed order — `account`, `marketplace`, `crm`, `notification`, `readiness`, `goLive` — each in one of five states: `done`, `current`, `todo`, `locked`, or `skipped`. Two rules are worth knowing before you build on it: - **Only `crm` and `notification` can be skipped.** The rest must actually be completed. - **Steps unlock in order.** `readiness` stays `locked` until your marketplace is connected, and `goLive` stays `locked` until readiness passes. The `readiness` step reports its own sub-checks — CloudFormation stack, seller account, data feed configured and flowing, commerce analytics, EventBridge, tax and banking, CRM connection, and notification channel — each `green`, `pending`, `red`, or `unknown`, so you can see exactly what is holding a launch up. :::info Progress is derived from your live configuration rather than stored, so it stays honest: delete an integration and the step that depended on it goes back to incomplete. The endpoint answers for seller organizations only. ::: ## New to the terms? If words like **offer**, **entitlement**, **private offer**, or **metering** are new, skim the [Key Terms glossary](/concepts/glossary/) first — it defines the vocabulary the rest of the docs use. ## Not sure Fours is a fit yet? Start with the concepts: [What Is Fours](/get-started/what-is-suger/) and [What Is a Cloud Marketplace](/concepts/what-is-cloud-marketplace/). --- Source: https://doc.fours.com/get-started/what-is-suger/ # What Is Fours Fours is a cloud go-to-market platform for selling and billing software through cloud marketplaces (AWS, Microsoft, Google Cloud, Snowflake, Alibaba Cloud, Oracle), with metering, invoicing, revenue reporting, CRM/PRM integrations, and workflow automation. It streamlines and centralizes the quote-to-cash process for cloud marketplace transactions, so you can manage every marketplace from one platform. Fours, formerly Suger, is an independent software company at [fours.com](https://www.fours.com/), operated by Suger, Inc. It is not affiliated with any similarly named CRM, marketing, or AI vendor. These docs are at doc.fours.com (the old doc.suger.io address 301-redirects here), and product identifiers — the console at console.suger.io, the API hosts on suger.cloud, `suger`-prefixed fields — still carry the former name. --- ## Overview Businesses increasingly use cloud marketplaces to reach buyers and sell software solutions and services. But managing transactions across multiple cloud marketplaces can be complex and time-consuming. Fours solves this by centralizing and automating the quote-to-cash process — helping you automate workflows, gain visibility, and optimize your operations across cloud marketplaces. ## What You Can Do with Fours Fours brings your entire cloud marketplace business into one platform: - **List and manage products** across the [AWS](/aws-marketplace/), [Microsoft](/azure-marketplace/) (Azure), [Google Cloud](/gcp-marketplace/), [Snowflake](/snowflake-marketplace/), [Alibaba Cloud](/alibaba-marketplace/), and [Oracle](/oracle-marketplace/) marketplaces from a single console. - **Create and manage offers** — public offers, private offers, channel partner (resale) offers, and amendments — without logging into each cloud portal. - **Meter usage and automate billing** so metered products are reported and invoiced accurately. See [Usage Metering](/metering/usage-metering/). - **Co-sell with the cloud providers** by syncing opportunities to the AWS, Microsoft, and Google co-sell programs. See [Co-Sell](/cosell/). - **Work from your CRM** so your sales team can transact directly from [Salesforce](/salesforce-app/) or [HubSpot](/hubspot-app/) opportunities. - **Run a partner program** with [PRM](/prm/): a branded portal for the companies that sell with you, with invitations, deal registration, commission plans, tiers, and training. - **Track revenue and analytics** across every marketplace in one place. See [Analytics](/analytics/). ## Automate Marketplace Workflows Fours streamlines managing transactions across multiple cloud marketplaces by automating tasks and workflows. - Fours centralizes all your marketplace activity into a single platform, so you no longer have to navigate multiple systems. - Automation reduces manual effort, minimizes errors, and accelerates the time it takes to generate revenue from transactions. ## Manage Everything in the Fours Console The [Fours Console](https://console.suger.io) is a centralized hub where you monitor and manage transactions from different cloud marketplaces. - A unified dashboard gives you visibility into all marketplace activity, including order processing, billing, and reporting. - Consolidating marketplace activity into one platform simplifies management, improves coordination, and increases operational efficiency. ## Integrate With Your CRM Fours integrates with popular CRM (Customer Relationship Management) platforms so data flows smoothly between systems. - Information stays synchronized across platforms, improving data accuracy and giving you more reliable customer insights. - You can streamline customer management and improve your private offer and co-sell engagement strategies on cloud marketplaces. ## Gain Visibility Into Quote-to-Cash Visibility into the quote-to-cash process helps you track transactions and make informed decisions. - Fours tracks transactions from the initial quote through to payment collection. - Built-in insights and analytics help you understand your transactional data, identify trends, and optimize your operations. ## Summary Fours provides a comprehensive way to simplify and optimize transactions across cloud marketplaces. By automating workflows, centralizing marketplace activity in the Fours Console, integrating with your CRM, and enhancing visibility into quote-to-cash, Fours helps you operate more efficiently and grow marketplace revenue. If you have further questions about how Fours can help with your cloud marketplace transactions, reach out to support@suger.io for guidance. ## Next Steps - [What Is a Cloud Marketplace](/concepts/what-is-cloud-marketplace/) — how marketplaces work and what each cloud requires before you can list. - [Resources](/concepts/resources/) — the core concepts (products, offers, entitlements, buyers) you'll manage in Fours. - [Account](/get-started/account/) — set up your Fours organization and invite your team. --- Source: https://doc.fours.com/get-started/integration-timeline/ # Integration Timeline Understand how long it takes to list and sell through the cloud marketplaces with Fours, based on which cloud providers and Fours products you use. --- ## Overview The integration timeline to list and sell using the Fours console depends on two key factors: the cloud provider and the Fours products you use. This page walks through both factors and how they affect the time to get up and running on the Fours platform. For the prerequisites you'll need to complete before you start, see [Marketplace Listing Requirements](/concepts/what-is-cloud-marketplace/#marketplace-listing-requirements). The timelines below are not cumulative — most tasks can be completed concurrently. :::info Keep these caveats in mind: - The timelines assume you've completed all prerequisites for each cloud platform. - Marketplace listings can be expedited, but only when there's an active deal in the pipeline. ::: ## Timelines by Cloud Provider ### AWS **Net new product listing (approx. 3 weeks)** To list and sell a new product on AWS using Fours: 1. Create product listing details — Fours uses templates to speed this up; time-box it to about an hour. 2. Integrate Fours with your AWS Marketplace account (AWS Marketplace Management Portal) — about 20 minutes with an AWS admin. 3. Submit for review — about 2 weeks with AWS. The work required from you as the project owner is roughly 2 hours. The rest is handled by the Fours and AWS teams, who test the product and make sure it goes live. **Listing migration (approx. 5 days)** To list and sell an existing AWS product using Fours: 1. Integrate Fours with your AWS Marketplace account (AWS Marketplace Management Portal) — about 20 minutes with an AWS admin. 2. Update fulfillment URLs — about 3 days with AWS review. ### Azure **Net new product listing (approx. 3 weeks)** To list and sell a new product on Azure using Fours: 1. Create product listing details — Fours uses templates to speed this up; time-box it to about an hour. 2. Integrate Fours with your Azure Marketplace account (Azure Partner Center) — about 20 minutes with an Azure admin. 3. Submit for review — about 2 weeks with Azure. The work required from you as the project owner is roughly 2 hours. The rest is handled by the Fours and Azure teams, who test the product and make sure it goes live. **Listing migration (approx. 5 days)** To list and sell an existing Azure product using Fours: 1. Integrate Fours with your Azure Marketplace account (Azure Partner Center) — about 20 minutes with an Azure admin. 2. Update fulfillment URLs — about 3 days with Azure review. ### GCP **Net new product listing (approx. 4 weeks)** To list and sell a new product on GCP using Fours: 1. Create product listing details — Fours uses templates to speed this up; time-box it to about an hour. 2. Integrate Fours with your GCP Marketplace account (GCP Producer Portal) — about 20 minutes with a GCP admin. 3. Submit for review — about 3 weeks with GCP. The work required from you as the project owner is roughly 2 hours. The rest is handled by the Fours and GCP teams, who test the product and make sure it goes live. **Listing migration (approx. 5 days)** To list and sell an existing GCP product using Fours: 1. Integrate Fours with your GCP Marketplace account (GCP Producer Portal) — about 20 minutes with a GCP admin. 2. Update fulfillment URLs — about 3 days with GCP review. ## Timelines by Product ### Salesforce Connector (approx. 1 hour) Connecting Fours to your Salesforce instance lets your team send private offers and share opportunities directly from Salesforce. You can also field-map all relevant Salesforce fields to private offer and co-sell fields, so you don't have to fill in the details for sending private offers or sharing opportunities with cloud providers. - Install the Fours Salesforce app from AppExchange and connect it to Fours — about 10 minutes for a Salesforce admin. - Add the pre-packaged widget to the opportunity object — about 5 minutes for a Salesforce admin. - Map relevant fields for private offer and/or co-sell creation, then test — about 45 minutes for a Salesforce admin, sales ops, or alliances lead. ### HubSpot Connector (approx. 10 minutes) Connecting to HubSpot lets you use Fours' co-sell capabilities from the Fours console. You'll need a HubSpot admin, and setup should take about 10 minutes. - Create a new dedicated HubSpot user with the required permissions — about 5 minutes. - Connect the Fours console to the new HubSpot user — about 5 minutes. ### AWS APN for AWS Co-Sell (approx. 30 minutes) Connecting to AWS APN for co-selling requires your alliance lead and an AWS admin. - Create IAM roles with an AWS admin — about 15 minutes. - Complete the CRM connector request in APN and connect APN to the Fours console — about 15 minutes. ## Who and What You'll Need - **Project owner** — likely the person reading this page. - **Marketplace admin** — often in the IT department at larger companies. - **Product listing content creator** — usually your alliances team or marketing department. - **CRM admin** — helps integrate Fours into your CRM if you're sending private offers from your CRM or co-selling. - **Sales enablement date** — mark a date on the calendar to enable your sales team on what a cloud marketplace is, and on co-selling if applicable. ## Sample Timeline **The scenario:** You want to get a new listing up on Azure but already have a listing on AWS. You'd like to use Fours to send private offers and share opportunities with AWS through Salesforce. How long will this take? **The plan:** The AWS listing can be migrated in about one week. The Azure listing takes about 3 weeks. Setting up co-sell on Salesforce, with the ability to send private offers, takes about one week. Because all of this can be done in parallel, the total time to be fully set up on Fours is about 3 weeks. ## Get Help By following these timelines and using the [Fours Console](https://console.suger.io), you can streamline listing and selling your products across cloud marketplaces. If you have questions or need help, reach out to our sales or support team at support@suger.io. --- Source: https://doc.fours.com/get-started/account/ # Account Manage user, organization & RBAC in Fours Console. --- ## Signup & Login 1. Fours uses [Auth0](https://auth0.com/) as the authentication & authorization provider. Both `Sign in` and `Sign up` share the same entry https://console.suger.io/login. ### Standard Login (Email and Password) Follow these steps if you have a registered Fours account with an email and password. 1. Email Address: Enter the email address associated with your Fours Console account. 2. Password: Type your password. 3. Complete Login: Once both fields are filled, click the "Continue" button to proceed to your account dashboard. ### Alternative Login Options Fours supports `sso` with `Google`, `Microsoft` and `OKTA` (available upon request). If you need `sso` with other identity providers like `OKTA`, please contact us at support@suger.io. * **Continue with Google:** Click the "Continue with Google" button to sign in instantly using your existing Google account credentials. * **Continue with Microsoft:** Click the "Continue with Microsoft" button to sign in using your existing Microsoft account credentials. If Fours has set up a custom SSO configuration for your organization, **Settings → SSO** shows it in a read-only **Custom SSO** section. The section lists whichever of these values are set: **Auth Provider**, **Auth0 Application Client ID**, and **Auth0 Enterprise Connection Name**. **Edit in Organization settings** opens the **Organization** tab, where those values are edited. If the organization has no self-service SSO connection, the SSO page says *"This organization has a custom SSO configuration (below) rather than a self-service SSO connection."* instead of *No SSO connections configured yet*. ### Creating a New Account If you are a new user and do not yet have an account: 1. On the login form, look for the text **"Don't have an account?"** 2. Click the **Sign up** button 3. Choose how you'd like to register — enter an email and password, or continue with **Google**, **Microsoft**, or **Okta**. 4. If you don't belong to an organization yet, Fours then opens **Join an Organization**. If your company's organization is listed there, ask to join it — see [Join an Existing Organization](#join-an-existing-organization). Otherwise, click **Create New Organization** and follow the on-screen prompts to name and create your organization. This will direct you to the registration page where you can create your new account credentials. :::info The account used to create the organization is automatically assigned the `ADMIN` role, and your organization's email domain is inherited from this account. New organizations require approval from Fours Support before they become active — see [Organization](#organization) below. ::: ### Join an Existing Organization If your company already has a Fours organization, ask to join it instead of creating a second one. While you're signed in but not yet a member of any organization, Fours opens **Join an Organization**, which lists the active organizations on your email domain. 1. Next to your company's organization, click **Join**. 2. Choose a **Requested Role**: **Viewer** (read-only access), **Editor** (view and edit), or **Admin** (full access, including user management). It starts at **Editor**. 3. Write a **Message** of 10 to 1,000 characters saying why you need access, then click **Submit Request**. Fours confirms with *"Join request submitted successfully!"*, marks the organization **Pending**, and emails its Admins. An Admin approves or rejects the request (see [Review Join Requests](#review-join-requests)), and Fours emails you the decision. If your request is rejected, click **Re-submit** to ask again. **Joining a partner organization is normally immediate.** Fours approves the request as soon as you submit it and shows *"You have joined the organization."* A request for **Admin** is granted as **Editor**. If the organization shows **Pending** instead, an Admin there reviews your request as usual. See [Let teammates join on their own](/prm/add-portal-users/#let-teammates-join-on-their-own). ### Password Management and Security If you cannot remember your password: 1. Click the **"Forgot password?"** link located above the **Continue** button. 2. Follow the on-screen prompts to initiate the password reset process. ### Multi-Factor Authentication (MFA) Fours supports Multi-Factor Authentication (MFA) for an additional layer of account security. When MFA is enabled, the **"Secure Your Account"** screen prompts you to register an authenticator during login. Before you start, make sure your device's clock is set to automatic date & time (e.g. **Settings → Date & Time → Set Automatically** on iOS, **Settings → System → Date & time → Automatic date & time** on Android). Your authenticator's codes are generated from the current time, so a device with an incorrect or manually-set clock will generate codes that don't match what Fours expects, and verification will keep failing even when you've entered the code correctly. 1. Open an authenticator app (for example, **Microsoft Authenticator** or **Google Authenticator**), or a password manager with a built-in one-time-password feature such as **1Password**. 2. In your authenticator, add a new account and scan the **QR code** shown on the Fours screen. 3. Enter the 6-digit code generated by your authenticator in the **"Enter your one-time code"** field, then click **Continue**. > Secure Your Account MFA setup screen with the Suger logo and a QR code :::tip If scanning the QR code does not register successfully (a common issue with Microsoft Authenticator), use manual entry instead: 1. On the Fours screen, click **Trouble Scanning?** to reveal the **setup key** (a text code). 2. In your authenticator app, choose **Add account** → **Other account**, then select **Enter code manually** (usually a small button near the bottom of the screen). 3. Type in the setup key from the Fours screen. Scanning the QR code and entering the setup key register the **exact same token** — scanning is only a shortcut, not a requirement. ::: :::note Register the setup key in **only one** authenticator. You can use Microsoft Authenticator **or** 1Password, but adding the same key to multiple apps can cause confusion during login. ::: On later logins, the **"Verify Your Identity"** screen asks for the current 6-digit code from your authenticator. You can select **"Remember this device for 30 days"** to skip the one-time code on that device on future sign-ins — within the limits described below. > Verify Your Identity screen with the Suger logo, a one-time code field and the Remember this device for 30 days option :::caution **"Remember this device for 30 days" may not keep you signed in for a full 30 days.** For account security, how long a device is remembered is tied to your sign-in session, and the platform does not let the two be configured separately. In practice, a trusted device is currently remembered for **up to 14 days**, and you'll be asked for your one-time code again after **3 days without signing in**. ::: :::note You may be asked for your one-time code again — even within that window — whenever the "remembered device" record stored in your browser is cleared. Common causes: - clearing your browser's cookies or site data; - signing in from a different browser or device, or in a private/incognito window; - a browser or extension configured to clear cookies when it closes. ::: :::tip To stay remembered for as long as possible, sign in from the **same browser** on the same device and avoid clearing cookies or using private/incognito mode. Keep your authenticator app handy for when the prompt does return. ::: ## Organization 1. All Fours resources are organized & managed under organization. Each user must belong to at least one organization. 2. When you sign up for Fours for the first time and don't belong to an organization yet, you will be prompted to join your company's existing organization or create a new one (see [Join an Existing Organization](#join-an-existing-organization)). However, please note that a new organization will require approval from Fours in order to become active. To initiate the approval process for your newly created organization, please get in touch with [Fours Support](mailto:support@suger.io). 3. **At most two organizations per email domain may await approval at once.** A third create is refused with a `409` naming how many are already in the queue. Wait for the pending ones to be reviewed before creating another. 4. The user who creates the organization has the `ADMIN` role as default. It is allowed to add new users, edit user role or delete the users. There are 3 predefined standard roles: `ADMIN`, `EDITOR` & `VIEWER`. Their permission scope is defined below: | User Role | Recommended for | RBAC Permissions | | --------- | -------------------------------------------- | :----------------------------------------------------------------------------------------------------- | | `ADMIN` | Business Technology, Sales Ops, IT/CRM Admins | Full access, including management of users, organizations, API Client & Webhook. | | `EDITOR` | Sales, Partnerships, Alliances, Deal Desk | Full access, but excluding the access to management of users, organizations, API Client & Webhook. | | `VIEWER` | Finance, Accounting, Executives | Can only access Fours services with `read` access, no permission to `create/edit/delete` any resources. **Exception:** Partner Management grants Viewers no access at all, not even read — see [Who can use Partner Management](/prm/#who-can-use-partner-management) | :::tip - The `email domain` of the organization inherits from the user who created it. - For security purpose, only the users who has the same `email domain` as the organization can be added to that organization. ::: ## Invite Your Team Once your organization is active, an Admin can add teammates. Inviting a user **pre-approves** their email for the Fours Console — it does **not** create an account. The invitee still has to sign up themselves to activate access. ### Invite a New Team Member 1. Go to [**Settings > Users & Roles**](https://console.suger.io/settings?tab=users_roles). 2. Click **New User** at the top right of the user table. 3. In **Add New User**, enter the user's **First Name**, **Last Name**, and professional **Email**, then select a **Role** — **Admin**, **Editor**, or **Viewer** (or a [custom role](#custom-role-with-granular-permissions)). 4. Click **Save**. Fours emails the user an invitation with a link to sign up. If that person had already asked to join your organization, Fours normally resolves their pending join request at the same time. When it does, it tells you: *"This user already had a pending join request for this organization — it has been resolved automatically."* :::warning Fours only allows invites to email addresses that share your organization's domain. A user with a different domain can't be added — this is a common reason an invite silently fails to reach the intended person. ::: ### Manage Users - **Monitor status**: Check the **Status** column in the user table to see whether an invite is still **Pending** or the user is **Active**. - **Update roles**: Click the **Edit** icon next to a user, then select a new role from the dropdown. - **Revoke access**: Click the **Delete** (or **Revoke**) icon next to a user to remove their access to the organization immediately. - **Reset MFA**: If a member is locked out of their authenticator, click the **Reset MFA** icon next to them to clear their registered factors so they can enroll a new one. See [Reset a Member's MFA](#reset-a-members-mfa). ### Review Join Requests When someone on your email domain asks to join your organization, Fours emails your organization's Admins and lists the request under **Pending Join Requests**, at the top of [**Settings > Users & Roles**](https://console.suger.io/settings?tab=users_roles). Only Admins can see and act on these requests, and the table appears only while at least one is waiting. Each row shows the first two lines of the requester's message, or **No message** if they didn't write one. Click the row, or the arrow at its start, to read the whole request: who asked, your organization, the role they asked for, when they asked, and their full message. One row opens at a time, and clicking **Approve** or **Reject** doesn't open or close it. - **Approve**: the **Approve Join Request** dialog repeats **Their message** (click **Show more** to read a long one). Choose the **Grant Role** — **Viewer**, **Editor**, or **Admin**. The role they asked for is marked **(requested)**, and the choice starts there. Click **Approve**, and they join with that role. - **Reject**: the **Reject Join Request** dialog repeats their message too. Optionally give a **Reason**, then click **Reject**. Either way, Fours emails the requester the decision, including your reason if you gave one. If your organization sells with Partner Management, **Manage in PRM →** beside the table's title opens **Partners > Applications > User access**. That list also keeps the requests you've already approved or rejected, and lets you decide several at once. See [Review requests to join your organization](/prm/collaborations/#review-requests-to-join-your-organization). **When the requester is already a member.** Someone can get access another way before anyone reviews their request — for example, you add them with **New User**, or they sign in through your company's single sign-on. Fours normally closes their pending request by itself when that happens. A request that stays open for someone who is already in your organization is marked **Already a member**: - Click **Approve** to clear it. No role dialog opens, and the role they already have doesn't change. - **Reject** is unavailable for that row. Its tooltip reads *"Already a member — use Approve to clear this request"*. Requests to join a **partner** organization are normally approved on submit, and only appear here if that automatic approval fails. See [Let teammates join on their own](/prm/add-portal-users/#let-teammates-join-on-their-own). ```d2 direction: right submit: "Teammate submits\na join request" pending: "Pending\nAdmins are emailed" approved: "Approved\nthey are a member" rejected: "Rejected\nrequester is emailed" submit -> pending: "any other organization\n(or partner approval fails)" submit -> approved: "partner organization:\napproved on submit" pending -> approved: "an Admin approves" pending -> rejected: "an Admin rejects" pending -> approved: "usually closed when they\nget access another way" rejected -> submit: "Re-submit" { style.stroke-dash: 4 } ``` ### Reset a Member's MFA If a teammate loses their phone, switches devices, or is otherwise locked out of their authenticator, an Admin can reset that member's MFA so they can enroll a new one — no need to contact Fours Support. 1. Go to [**Settings > Users**](https://console.suger.io/settings?tab=users_roles). 2. Find the member in the user table and click the **Reset MFA** icon in their row. 3. Confirm the action in the dialog that appears. ![Reset MFA icon in a user row on the Users & Roles page in the Fours Console](images/reset-mfa.png) What happens next: - The member's registered MFA factors (authenticator-app codes and passkeys) are cleared. - On their next login, the **"Secure Your Account"** screen prompts them to register a new authenticator — the same as [first-time MFA setup](#multi-factor-authentication-mfa). :::note - Only **Admins** can reset MFA, and only for members of their own organization. - The reset itself is **account-wide, not scoped to your organization**. The confirmation dialog says so: it clears MFA for the member's entire Fours account, including any other organizations they belong to. - Resetting MFA does **not** change the member's password, remove them from the organization, or affect their role. - It temporarily lowers the member's account security until they re-enroll, so only reset MFA when the member has genuinely lost access to their authenticator. ::: ### Complete the Onboarding (For Invited Users) Once invited, a new teammate follows these steps to activate their account: 1. **Open the invitation email**: Check your inbox for an email from Fours with the subject line **"Hi [Your Name], you have been invited to Fours"**, then click the **Create your account** button. 2. **Establish credentials**: The button takes you straight to the Auth0 **Sign Up** form with your email address already filled in — you don't need to switch over from the login form or retype your address. - **Standard signup**: Set a secure password to create your account. - **If SSO is enabled**: Use **Continue with Google**, **Microsoft**, or **Okta/SSO** to register with your company credentials instead of a password. 3. **Verify your email**: After you set a password, a **"Verify your email"** dialog appears — _"Your account is created. We sent a verification link to [your email address]."_ Open that link from your inbox to activate the account. Following the link brings you back to Fours and logs you in automatically; if you'd rather finish in the tab you already have open, click **I've verified — continue** there once you've opened the link. 4. **Access the console**: After a successful login, you land on the Fours Dashboard with the access level your Admin assigned. ## Custom Role with Granular Permissions Custom roles offer precise control over permissions, allowing you to go beyond the limitations of predefined standard roles, which may be overly broad. This flexibility enables assigning specific permissions at a more granular level — you can toggle **Read**, **Write**, and **Delete** per console module (for example, **Billing**, **Co-Sell**, or **Private Offers**). ### Create Custom Role 1. Navigate to the [settings page](https://console.suger.io/settings) of your organization. 2. Locate the `Roles` section under the `Organization & Users` tab. 3. Click the `Add Custom Role` button. 4. Fill in the name and description fields. 5. Set permissions according to your specific requirements. > Add Custom Role form with name, description, and permissions ### Assign Custom Role to User Once custom roles are created, you can apply them during the creation or modification of a user. 1. Visit the [settings page](https://console.suger.io/settings) of your organization. 2. Find the `Users` section under the `Organization & Users` tab. 3. Add a new user by clicking the `Add User` button or edit an existing user by clicking the edit button in each user row. 4. Set the role field in the `Add User`/`Edit User` dialog to the desired custom role. ### Edit Custom Role 1. Visit the [settings page](https://console.suger.io/settings) of your organization. 2. Locate the `Roles` section under the `Organization & Users` tab. 3. Click the edit button in each custom role row. 4. Modify the name, description, and permissions as needed. Once saved, the updated permission set applies to every user currently assigned to that role. > Edit Custom Role form with name, description, and permissions ## Use Okta as Identity Provider Fours supports **Okta** as an identity provider, allowing centralized user authentication and access management through your Okta account. Refer to [Okta SSO](/integrations/okta-sso) for more details. ## Troubleshooting | Issue | Possible cause | Resolution | | --- | --- | --- | | QR code won't scan when setting up MFA | Common with Microsoft Authenticator specifically | Click **Trouble Scanning?** on the Fours screen to reveal the setup key. In your authenticator, choose **Add account → Other account → Enter code manually**, then type in the setup key. Scanning the QR code and entering the setup key register the exact same token. | | MFA code is rejected even though you entered it correctly | Device clock isn't set to automatic date & time, so the authenticator generates a code for the wrong moment in time | Turn on automatic date & time in your device's settings, then wait for a new code to generate before retrying. | | Invite doesn't reach the intended person | Email address doesn't share the organization's domain | Confirm the invitee's email matches your org's domain. Fours only allows invites within the same domain. | | **Reject** is greyed out on a join request | The row is marked **Already a member** — the person got access another way before anyone reviewed the request | Click **Approve** to clear the request. Their existing role doesn't change. | ## Frequently Asked Questions **Q: Does inviting someone create their Fours account?** A: No. It only pre-approves their email for signup. They must complete registration themselves. **Q: Can I invite someone with a personal or different-company email?** A: No — invites are restricted to users sharing your organization's email domain. **Q: What's the difference between a standard role and a custom role?** A: Standard roles (Admin, Editor, Viewer) are fixed. Custom roles let you toggle Read/Write/Delete permissions per module for more granular control. **Q: Do I have to enter my MFA code every time I log in?** A: No — select **"Remember this device for 30 days"** on the Verify Your Identity screen to skip MFA on that device for 30 days. **Q: A teammate lost the phone with their authenticator — how do they get back in?** A: An Admin can reset that member's MFA from **Settings > Users**. On the member's next login, they'll be prompted to set up a new authenticator. See [Reset a Member's MFA](#reset-a-members-mfa). --- Source: https://doc.fours.com/get-started/connect-your-marketplace/ # Connect Your First Cloud Marketplace Once your organization is [approved](/get-started/account/), connecting a cloud marketplace is the first real setup task. It links your seller account on a cloud (AWS, Azure, GCP, and more) to Fours, which unlocks products, offers, metering, and billing for that channel. --- ## How it fits together ```d2 direction: right acct: "Approved Fours org" pick: "Which cloud do\nyou sell through?" { shape: diamond } aws: "Connect AWS" az: "Connect Azure" gcp: "Connect GCP" other: "Snowflake / Alibaba / Oracle" ready: "List products & create offers" acct -> pick pick -> aws: AWS pick -> az: Azure pick -> gcp: GCP pick -> other: Other aws -> ready az -> ready gcp -> ready other -> ready ``` ## Before you connect Each cloud marketplace requires a seller account and some one-time account, legal, and tax setup on the cloud's side before Fours can connect to it. Those prerequisites — and who on your team you may need (an admin, finance, or engineering teammate) — are covered in [What Is a Cloud Marketplace](/concepts/what-is-cloud-marketplace/). The step-by-step connection for each cloud lives in that cloud's own section, linked below. ## Pick your cloud Open the onboarding guide for the marketplace you sell through: | Cloud marketplace | Start here | |-------------------|------------| | **AWS Marketplace** | [Connect AWS](/aws-marketplace/integration/) · [AWS Marketplace section](/aws-marketplace/) | | **Azure Marketplace** | [Connect Azure](/azure-marketplace/integration/) · [Azure Marketplace section](/azure-marketplace/) | | **Google Cloud Marketplace** | [Connect GCP](/gcp-marketplace/integration/) · [GCP Marketplace section](/gcp-marketplace/) | | **Snowflake Marketplace** | [Connect Snowflake](/snowflake-marketplace/integration/) · [Snowflake section](/snowflake-marketplace/) | | **Alibaba Cloud Marketplace** | [Connect Alibaba](/alibaba-marketplace/integration/) · [Alibaba section](/alibaba-marketplace/) | | **Oracle Cloud Marketplace** | [Connect Oracle](/oracle-marketplace/integration/) · [Oracle section](/oracle-marketplace/) | You can connect more than one marketplace — Fours manages every channel from one place. ## What "connected" means An integration moves through three states, and only one of them counts as done: | Status | Meaning | | --- | --- | | `CREATED` | Fours has the integration record but has not yet confirmed it can reach the marketplace. | | `NOT_VERIFIED` | Verification ran and did not pass. Fix what the error names, then verify again. | | `VERIFIED` | Fours can reach the marketplace with the credentials you supplied. This is the state the rest of the product depends on. | Onboarding treats your marketplace step as complete only once a **verified** AWS, Azure, or Google Cloud Marketplace integration exists — a `CREATED` record is not enough. ### Two settings worth knowing about up front **Opening the cloud console from Fours can be switched off.** By default an admin can jump straight into the AWS console from the integration row. Your organization can have that turned off, in which case the button is still there but returns: > Console access to AWS has been switched off for your organization. Contact your Fours administrator to > restore it. The switch is organization-wide, covers both the Marketplace and Billing destinations, and is set by Fours rather than from your own settings page — so if you need it back, raise it with your Fours administrator or [support@suger.io](mailto:support@suger.io). **Google Cloud has an API-generation choice.** The GCP integration carries an **Enable PrivateOffer API** toggle. Turn it on and Fours syncs your Google Cloud Marketplace products and private offers through the GCP Commerce Producer API, and creates and replaces private offers through it. It also cancels and extends private offers through the API once it has recorded the offer's Google ID. Reseller authorizations (`CPPO_OUT`) are the exception — they stay on the older path because the Commerce Producer SDK does not cover them yet. See [About Enable PrivateOffer API](/gcp-marketplace/integration/#about-enable-privateoffer-api). ## After you connect - **Add a product** — create or import your marketplace listing. → [Products](/console/products/) - **Create an offer** — make your first sale with a private offer. → [Private Offers](/console/private-offers/) - **Find your way around** — see where everything lives. → [Navigate the Fours Console](/get-started/navigate-console/) --- Source: https://doc.fours.com/get-started/navigate-console/ # Navigate the Fours Console Find your way around the Fours Console using the left navigation menu and the top bar tools. --- ## Overview The Fours Console is organized into two areas. The menu on the left side of your screen is your primary control center for your quote-to-cash flow. The top bar gives you quick access to tools that help you work faster and get support. ## Main Navigation Menu Use the left-hand menu to move between the core areas of your quote-to-cash workflow. ### Home Use this as your daily starting point. It gives you a quick snapshot of marketplace health, revenue movement, and key operational changes. If something is off in your pipeline or revenue flow, you'll usually spot it here first. ![Home page in the Fours Console](images/navigate-the-suger-console-1.png) ### Product Use this when you are preparing something to sell. This is where you create and manage product listings across AWS, Azure, and GCP. Come here when launching a new product, updating listing details, or maintaining existing marketplace offerings. ![Product page in the Fours Console](images/navigate-the-suger-console-2.png) ### Offer Use this when you are actively closing deals. From here, you can create and track Private Offers sent to buyers. ![Offer page in the Fours Console](images/navigate-the-suger-console-3.png) ### Resale Use this when working with partners or channel-led deals. This is where you manage CPPO (Channel Partner Private Offers) and handle resale authorizations. ![Resale page in the Fours Console](images/navigate-the-suger-console-4.png) ### Entitlement Use this when you need the truth of "who actually bought what." This is your system of record for active contracts, subscriptions, and accepted offers. ![Entitlement page in the Fours Console](images/navigate-the-suger-console-5.png) ### Company Use this when working on account-level visibility. It consolidates everything about a buyer account, including activity, financial history, and enriched company data. ![Company page in the Fours Console](images/navigate-the-suger-console-6.png) ### Contact Use this to manage people, not companies. This is your directory of buyers, admins, and partner contacts tied to deals and accounts. ![Contacts page in the Fours Console](images/navigate-the-suger-console-7.png) ### Usage Metering Use this when billing depends on consumption. Report and review usage-based data that drives metered billing and downstream invoices. ![Usage Metering page in the Fours Console](images/navigate-the-suger-console-8.png) ### Revenue Use this when finance needs clarity across connected revenue channels. **Revenue** opens the Overview and provides these visible workspace pages: - **Operations** — Overview, Revenue Records, Invoices, Cash & Disbursements. - **Analytics** — SaaS Metrics, Channel Performance, Financial Reports. - **Settings** — reporting policies, channel sync configuration, and connected bank accounts. ![The Revenue workspace — its own navigation with Overview, Revenue Records, Invoices and Cash & Disbursements under Operations, and SaaS Metrics, Channel Performance and Financial Reports under Analytics, beside the revenue lifecycle stage cards](images/revenue-workspace.png) ### Co-Sell Use this when working with cloud providers on pipeline acceleration. Track and manage CRM-linked opportunities shared with AWS, Azure, or GCP teams. ![Co-Sell page in the Fours Console](images/navigate-the-suger-console-10.png) ### Partner Use this to understand your ecosystem performance. This is where you track partner influence, pipeline contribution, and channel health. ![Partners page in the Fours Console](images/navigate-the-suger-console-11.png) ### Funding Use this when deals need acceleration support. Submit and track funding requests for AWS funding programs that help move deals forward. ![Funding page in the Fours Console](images/navigate-the-suger-console-12.png) ### Analytics Use this when you need answers, not raw data. Build dashboards to understand performance across revenue, deals, usage, and partners. ![Analytics page in the Fours Console](images/navigate-the-suger-console-13.png) ### Workflows Use this when something repeats. Automate operational tasks like syncing data, updating records, or triggering external systems. ![Workflows page in the Fours Console](images/navigate-the-suger-console-14.png) ### Tasks Use this when a running workflow needs a person. Tasks lists the workflow steps that are waiting on human input — an approval or a decision a workflow paused for — so a run does not sit stalled where nobody sees it. ### Settings Use this when you need control over the platform. Manage users, roles, integrations, and system configuration. ![Settings page in the Fours Console](images/navigate-the-suger-console-15.png) ## Top Bar Tools While the left-hand navigation menu handles your daily quote-to-cash tasks, the top bar gives you quick access to tools that help you work faster and get support. ### Organization Selector The **Organization selector** in the top bar shows the workspace you're currently using. If you have access to multiple organizations, you can use it to switch between them. In Fours, all cloud marketplace resources, user roles, and integrations are managed within an organization. Every user must belong to at least one organization to use the platform. ![Switching organization in the Fours Console](images/navigate-the-suger-console-16.png) ### Global Search Use **Global search** in the top bar to find your cloud marketplace and CRM records without leaving your current task. ![Global search in the top bar menu in the Fours Console](images/navigate-the-suger-console-17.png) ### Timezone Selector Cloud marketplaces universally report data in Coordinated Universal Time (UTC). While this creates a consistent global record, it can confuse sales and finance teams trying to see exactly when a private offer expires or when an invoice was issued. The **Timezone selector** solves this by localizing timestamps directly in your workspace. ![Timezone selector in the Fours Console](images/navigate-the-suger-console-18.png) ### AI Chatbot The **AI chatbot** is your built-in assistant, always available in the top bar. It gives immediate answers to your platform questions, explains complex marketplace concepts, and helps you navigate Fours without leaving your current workspace. The assistant in the top bar is the compact view. The full product behind it is [Fours Insulin](/insulin/) — an AI workspace with its own agents, knowledge bases, jobs, and apps. Use the panel for a quick question; open Insulin when you want the assistant to do sustained work. To use it, click the **AI chatbot** icon in the top bar, and a side panel opens directly over your screen. Here's a breakdown of the chatbot panel and its controls: - **New chat (+)**: Start a fresh conversation. Use this when switching to a completely new topic or workflow so the AI doesn't mix your questions with previous sessions. - **Chat history (clock icon)**: View past conversations. You can pick up right where you left off, or use the vertical three-dot menu next to any session to rename or delete it for better organization. - **Close panel (arrow icon)**: Hide the overlay and return to your full-screen workspace. Your current conversation is automatically saved in the chat history. ![AI chatbot panel and key menus in the Fours Console](images/navigate-the-suger-console-19.png) ### Support The **Support** tool in the top bar is your direct, in-product portal to communicate with the Fours team. Use this when something breaks or needs tracking. Click the **(?) icon** to open the **Support** page (partner organizations on the limited partner console don't have this icon). Depending on your role, its **Support Tickets** tab lets you follow your organization's tickets and open new ones — see [Support Tickets](/console/support-tickets/) for how tickets work and who can do what. The **AWS Support** tab holds the cases you open with AWS — see [AWS Support Cases](/aws-marketplace/support-cases/). ![Support menu in the Fours Console](images/navigate-the-suger-console-20.png) ### Notifications The **Notifications** tool in the top bar is your real-time alert hub for critical cloud marketplace events. It gives instant visibility into offer acceptances, entitlement changes, and billing milestones, so your team never misses a key update in the quote-to-cash lifecycle. Click the **bell icon** to open the **Notifications** panel, which slides out on the right side of your screen. Events are displayed in chronological order, with the newest at the top, giving you an instant view of everything happening across your organization. - **Search and filter**: Use the search bar to quickly find updates by Entity ID, Event Type (like `CREATE` or `ACCEPT`), or Status (like `EXPIRED` or `ACTIVE`). - **Org-wide feed**: Everyone in the same Fours Organization sees the same activity feed, ensuring your Sales, Alliances, and Finance teams share a single source of truth. ![Notifications panel in the Fours Console](images/navigate-the-suger-console-21.png) ### Profile The **Profile** menu shows your name and email so you always know which account is logged in. You can log out securely from here. All other account settings, like roles, passwords, or API keys, are managed in the main **Settings** menu. ![Profile menu in the Fours Console](images/navigate-the-suger-console-22.png) --- Source: https://doc.fours.com/get-started/faq/ # FAQ Frequently asked questions about marketplace payments, private offers, listings, and integrations in Fours. To find something quickly, use your browser's search (Ctrl+F). For help, contact Fours support via the in-app support chat or email support@suger.io. :::info Questions about what *you* pay Fours for AI usage — credits, tokens, spending limits and invoices — moved to the [Insulin billing FAQ](/insulin/billing/faq/). ::: ## AWS: Billing, Payments, and Tax ### Who do I receive payment from? Payment is always deposited into your registered bank account. To check your registered bank account, visit the **Payment Information** section on AMMP under [Seller Settings](https://aws.amazon.com/marketplace/management/seller-settings/account). ### How much listing/transaction fee does AWS take? Listing fees depend on the type of listing, the total contract value (TCV) of the offer, and the type of offer. AWS's official [listing fees documentation](https://docs.aws.amazon.com/marketplace/latest/userguide/listing-fees.html) covers the fee structure for all scenarios. ### When is the customer billed? AWS bills the customer in one of three ways: 1. **Date of subscription acceptance** (upfront billing) 2. **Custom payment schedule** (private offers built with a flexible payment scheduler) 3. **Metered usage** — billed on the second and third day of the month for the prior month's usage ### When will I receive money from AWS? Every customer agrees to net payment terms with AWS — either net 30, 45, 60, or net 0 for credit cards. Once a customer receives the bill, they must pay within the agreed terms. Every seller has a disbursement cycle, which you set up under settings. There are two cycles — **daily** and **monthly**. You can receive money as soon as AWS receives it, or on a specific date every month. To configure this, go to AMMP > [Payment Information](https://aws.amazon.com/marketplace/management/seller-settings/account) > Update Banking Information > Disbursement Preference. ### Do I need to charge and remit taxes separately? It depends, and the only authoritative answer is AWS's own grid — not a country-level rule of thumb. AWS is responsible for sales tax / VAT / GST in the jurisdictions listed in the [AWS Marketplace Sellers Tax Grid](https://aws.amazon.com/tax-help/marketplace-sellers/tax-grid/). Where AWS is not the responsible party, the seller or the buyer is. Which applies to a given transaction depends on the buyer's and seller's countries, the product type, which AWS legal entity operates the marketplace in that region, and your own tax registration status. Check the Seller Tax Grid for the countries you sell into, and confirm the result with your tax adviser — AWS gives the same advice in its [marketplace seller tax help](https://aws.amazon.com/tax-help/marketplace-sellers/). :::warning Do not assume "AWS handles all the taxes." That is true only for the jurisdictions in the Tax Grid. ::: *Last verified against AWS documentation: August 2026.* ### What should I do if there's a delay in receiving payments from AWS? Create a ticket with AWS Support using the [Contact Us form](https://aws.amazon.com/marketplace/management/contact-us/). ### How do I process refunds? You can process a full or partial refund to the buyer by submitting the [refund request form](https://aws.amazon.com/marketplace/management/support/refund-request). You can request a refund even when the buyer has not yet paid the invoice. In the additional comments section, mention that the charges should be waived if they are unpaid. ### Where can I check the status of a refund ticket? There isn't a place to check refund status directly — follow up on the AWS support email thread and ask for an update. AWS should be able to handle refund requests within a few days. ### Can I invoice a customer in their currency? Yes, for private offers, in the currencies AWS supports. AWS is not USD-only. | | | |---|---| | **Supported currencies** | USD, EUR, GBP, AUD, JPY — plus INR for India-based sellers only | | **Pricing types** | Contract, Contract with consumption (CCP), and pay-as-you-go (PAYG) | | **Container products** | Contract-only private offers can be priced in a non-USD currency. CCP and PAYG container pricing stays in USD | | **Before you can use it** | Configure a disbursement preference for each currency you intend to offer in — AWS requires this before you can create an offer in that currency | If you price in USD and the buyer's account is set to another currency, AWS converts at the exchange rates it publishes daily and bills the buyer in their own currency. See AWS's [multi-currency pricing for private offers](https://docs.aws.amazon.com/marketplace/latest/userguide/multi-currency-pricing.html) and the [supported currencies list](https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-paying-for-products.html#supported-currencies). *Last verified against AWS documentation: August 2026.* ### An offer was accepted, but the payment transaction failed. Can it be reprocessed? If a private offer acceptance fails due to an issue with the customer's payment method or account, the customer can accept the same private offer again once it's fixed. The failed attempt didn't generate an entitlement because it wasn't processed, so they can reuse the same offer link and it should work. ### The customer tried to accept an offer several times and gets an acceptance email followed immediately by a cancellation email. What's wrong? There are three main reasons an offer acceptance might fail: 1. The person accepting the offer doesn't have the proper permission to complete the transaction. 2. Their credit card operator declined the transaction, or their account isn't correctly set up for payment. 3. AWS can reject the transaction if the buyer hasn't paid their latest billing. Usually it's a problem with the customer's credit card or payment account. Contact the customer to help verify the transaction. During discovery, ask whether they're on Invoice or Credit Card with AWS. If they're on a credit card, tell them to make sure their bank knows this transaction is about to be processed so it isn't rejected — card companies often reject large transactions as possible fraud. ## AWS: Private Offers (MPPO/PO) ### How do I find out when a private offer is accepted? Once the offer is accepted, you're notified via email, and the offer status in Fours updates to **Accepted**. ### How do I cancel a private offer? A **Cancel Offer** button is on the offer details page inside the console. ### How does payment for a private offer work? For a flat commit, the customer is invoiced based on the payment schedule. If no payment is scheduled, they're invoiced on acceptance day or a few days after. Disbursement then happens based on their payment terms with the cloud provider. The cloud provider typically disburses those funds a few days after they're disbursed to AWS. ### I created an offer with the wrong EULA. Can it be updated? Once an offer is created, it can't be updated. Cancel it and recreate it — you can clone it and attach the correct EULA to the new one. ### A customer wants to add another group of users (an expansion). What's the best way to do this? Create an **Agreement-Based Offer (ABO)**, which Fours calls an Upsell/Renewal Offer. ### We're doing a renewal. If the offer has expired, do we make an Agreement-Based Offer or a new offer? If the offer has expired, create a regular private offer. ### I need to extend the expiry of a private offer by two weeks, but it's failing. What should I do? Extending won't work if you have a payment installment date set before the two-week extension. Create a new offer and set its first installment date as the expiration date. ### I tried creating an AWS offer via Fours and got "Failed to create offer: Offer PaymentTerms.Schedule.ChargeOn is not valid." You likely set the offer's charge date to a past date. It must be in the future. ### A customer provided the wrong AWS account number. How do I update the offer? You can't change the AWS account number on an existing offer. Clone the existing offer, update the AWS account number, push the new offer to the customer, then cancel the previous one. ### We didn't see an acceptance confirmation in AWS Marketplace and got no email notifications. How do we set up proper notifications? Whenever you see an entitlement associated with an offer, it means the offer was accepted. Fours can funnel notifications into your Slack channel for internal purposes. For external people (end buyers), add them as contacts on the offer, either when you create it or afterwards. Fours emails those contacts only when two conditions are met: - **Enable Email Notification** is on. - The **Accept Offer** row (`ACCEPT.OFFER`) is saved switched on with the **Offer Notification Contacts** rule. See [Email Notification](/settings/email-notification/#offers). ### A rip-and-replace offer can't be accepted because of "You already have a contract for this product." To process an upsell or renewal for a customer with an existing offer, do it from the existing agreement/entitlement. Go to the specific entitlement, click the **Upsell/Renew** button, and enter the upsell details. This lets the customer accept the new agreement given the change in terms. Note: if an installment has already been paid, the upsell is net of the amount already paid — the second installment will be the total amount for the second year of the upsell. ### When a customer accepts an offer, is anyone from AWS notified? AWS gains visibility only when you launch the opportunity and link that opportunity to the offer during the launch process. ### Can I set a future start date for a renewal offer, like I can for initial private offers? For renewal offers, the start date is always the acceptance date — you can only control the end of the contract. ### What is the lifecycle of an entitlement? When do "Pending Cancel" and "Cancel" events fire? What happens at the end of the term without auto-renewal? When a private offer is accepted, it automatically generates an entitlement/agreement. The customer controls that agreement and can stay subscribed or unsubscribe. If they unsubscribe, AWS notifies you within hours that the agreement was canceled. You receive both **PENDING CANCEL** and **CANCEL** webhook events from Fours — the gap between the two is usually about 1 hour. Without auto-renewal, the contract expires after the contract end date, and AWS notifies you that the agreement was canceled. To continue with the customer, create a new private offer. ### Our customer's active offer ends June 14th. If I set a new offer with a June 15th start date, can they accept it early on June 5th? Yes. They can accept the offer early as long as the start date is after the end of the ongoing contract. ### Does AWS Marketplace support auto-renew for offers? When end buyers self-serve and purchase the public SaaS listing, they can choose auto-renewal and switch it later. The seller/ISV cannot edit it. Private offers can auto-renew too. When you create a Contract, Professional Services, or Container private offer with committed pricing, you can add [pre-authorized auto-renewal](/aws-marketplace/pre-authorized-auto-renewal/) terms, which the buyer accepts along with the offer. ### When I generate a private offer link, who gets notified besides the customer and our Account Executive? When the offer is ready, Fours emails the offer's contacts, plus any addresses set on the **Pending Acceptance** row. That happens only when **Enable Email Notification** is on and the **Pending Acceptance** row (`PENDING_ACCEPTANCE.OFFER`) is saved switched on with the **Offer Notification Contacts** rule. AWS isn't notified. During creation, you can add your success manager, PDM, or any other AWS rep as a contact for those offers. ### Why doesn't the point of contact automatically appear on renewal private offers? In a renewal deal, the offer is created from the entitlement rather than the opportunity, so contacts aren't auto-populated from the opportunity owner. ### Does the opportunity owner get an email when the offer is accepted, or when it's ready? Yes, if the owner is a contact on the offer and your email configuration sends those emails. The offer's contacts are emailed when the offer is ready and when it is accepted, provided that: - **Enable Email Notification** is on. - The **Pending Acceptance** and **Accept Offer** rows are each saved switched on with the **Offer Notification Contacts** rule. See [Email Notification](/settings/email-notification/#offers). ## AWS: Channel Partner Private Offers (CPPO) ### How do we know when a CPPO is accepted? Is there a notification in Fours? Once the entitlement is about to start, AWS sends a confirmation that the customer signed the contract, and you'll also see a confirmation of a new offer in the Fours console. ### A CPPO offer accepted in March needs 30 more licenses added. Can we send another CPPO that overrides it and starts a new agreement immediately? Only the reseller can create an Agreement-Based Offer to add the 30 additional users. Ideally, a situation like this is managed through metering — customers who accept an offer with an additional usage option agree to pay future overages, which is why it's the ideal solution. There's no way to replace an existing CPPO offer. In a CPPO, the agreement exists between the customer and your reseller. ## AWS: Listing Creation and Changes ### Can everything on the listing be changed at any time? How long does it take? Everything can be changed at any time except pricing, which can only be changed every 120 days and requires an AWS support ticket. ### We have two products. Can we create two listings at the same time? Yes. ### If we remove a plan from our listing, how does it impact existing customers? It depends on your listing type. It should not impact customers on a flat-fee contract, but customers on a subscription might be affected. In that case, open a ticket with AWS and they'll tell you whether they can remove the dimension. ### Do we need to include the tax value in the price? Price your product exclusive of tax. Where AWS is the responsible party for a transaction, AWS calculates and adds the tax on top of your price, so building it into the price would double-charge the buyer. Where AWS is *not* the responsible party, you or the buyer settles the tax separately — again, outside the listed price. Which of the two applies is decided by the [Seller Tax Grid](https://aws.amazon.com/tax-help/marketplace-sellers/tax-grid/), not by a blanket rule — see [Do I need to charge and remit taxes separately?](#do-i-need-to-charge-and-remit-taxes-separately) above. *Last verified against AWS documentation: August 2026.* ## AWS: Security ### My security team asked about the KMS access policy. How does Fours use KMS in our account? KMS access is used only for syncing your marketplace revenue and buyer report data. AWS requires all S3 buckets that hold marketplace revenue and buyer reports to be encrypted with a KMS key, which is created via the CloudFormation template AWS provides. Fours doesn't require general access to your KMS resources — access is limited to the key related to this data sync. For setup details, see [AWS Marketplace integration](/aws-marketplace/integration/#marketplace-data-feeds-service-mdfs). ## Azure ### We only want to sell via the Azure marketplace. Do we need extra development? No. You can get your solution listed on Azure without any extra development. ### Can I transact with a private (not publicly visible) listing? No. Azure doesn't allow private listings to be transactable, so the product must be live. ### Can I cancel an Azure offer from Fours? A customer's offer auto-renewed and we need to cancel and refund it. There's no cancel button in Microsoft Partner Center. You can cancel it in the Fours console by clicking the **Cancel** button — but you must cancel the **entitlement** rather than the offer. ### Do I need the client's Azure ID to create the Fours offer? You'll need their **Azure Billing ID** to submit the private offer. ### A customer accepted and purchased our product, but our dashboard doesn't reflect it. The offer has been accepted and purchased. This happens because when the entitlement is created, Azure doesn't initially tell us which private offer was purchased. The entitlement is connected to the private offer later — this can take a few hours via the Azure marketplace CMA report sync. ### The EULA I attached to the Azure offer needs adjustments. How do I change it? You can't edit an ongoing offer. The best option is to cancel the existing offer and create a new one. ## GCP ### Is Google Cloud Validated Solution designation required to list in the marketplace? Yes, it is required. ### Is it common for GCP vendors to list no pricing and default to "talk to sales"? Yes. You can hide all your pricing plans in the public GCP marketplace listing — some clients use this configuration. It's a common strategy in B2B SaaS, giving sales more flexibility to negotiate deals, and it's straightforward to configure. ### Why is the IAM binding set to "allUsers" instead of a specific group or service account? Setting it to "allUsers" makes the listing public and live, so any GCP client can purchase and subscribe to your listing service. ## Fours Console: New Client Sign-Up Page ### Do you build the sign-up form, or do we? Fours handles creation of the client sign-up form for marketplace. You provide some basic details, such as company name and logo, and Fours creates the registration form automatically. ### How do I update my new user sign-up page? Go to **Settings > New Client Sign Up** in the Fours console. ### When do clients see the sign-up page during purchase? After they complete the purchase, they're immediately redirected to the sign-up page. ### What is the CC Emails field? Emails that will be CC'd on the confirmation email sent to the client. ### Is an email sent after the client leaves their details on this page? Yes. After the customer completes the form, Fours sends them a confirmation. ### Does "Public Notes" appear on the page? Yes. You can add any additional note you want, and it appears on the page. ## Integrations: HubSpot ### Does the integration with ACE auto-update when deals are closed/lost or the close date changes? Yes. Once an opportunity is submitted through Fours, future updates on your HubSpot deal flow to Fours — depending on how your mapping is set up. ### Do I have to refresh the Fours sync with ACE for changes to flow through? No. Once an hour, Fours scans your pipeline and the deals associated with an ACE record, collects the data, and updates the ACE records based on your mapping. Any changes made to a deal in HubSpot should appear on ACE within a few hours. ### Buyers don't have any contacts. When we map, will every buyer record have a full email address sent to HubSpot? By default, buyers don't have a contact associated with them. With Fours, future buyers will — this is a feature Fours offers that AWS doesn't. This only applies to new buyers after the integration. ### Can we build the "propensity to buy" metric into the data integrated with HubSpot? Yes. This is part of the Co-Sell implementation. When you submit a HubSpot deal to AWS, Fours collects the engagement score for that customer and sends it back to HubSpot. You just need to provide the field where you want to store the information. ## Integrations: Salesforce ### How does the AWS opportunity score show in Salesforce after the opportunity is accepted and scored? It appears on the referral record detail page. The field's API name is `Suger__AWS_EngagementScore__c`, in case you'd like to set up automation or formula fields. That field holds AWS's own score for the opportunity and nothing else, so a blank value means AWS has not scored that opportunity yet. Fours' own **Suger Predicted Engagement Score** is shown separately, in the Fours widget on the Account and Opportunity pages; it is not stored on the referral record, so it will not appear in a report, list view or formula built on this field. See [Co-sell Insights](/cosell/co-sell-insights/). ### I can't set up the opportunity ID for the partner CRM unique ID in the Salesforce field section. That field is mapped by default, so you don't need to set up mapping for it. ### After creating an offer, the "Copy Offer URL" button on the offer object in Salesforce does nothing. Why? After an offer is created, wait 3 to 5 minutes for it to be created in AWS Marketplace before you can copy the link. During that time, Fours sends the offer data to AWS to create the offer. Refresh the page after a few minutes and the Offer URL will be available in the Copy button. ### Can we do Agreement-Based Offers (ABO) from Salesforce, or do we need the Fours console? Yes, you can do it from Salesforce. ### I'm creating my first offer in Salesforce and everything is filled in except the API name. How do I find it? You define the API name for your new dimensions. Use the same dimension name in lowercase with underscores instead of spaces. ### I created a referral directly in ACE that's now validated. Will it show up in Salesforce, and how do I connect it to a Salesforce opportunity? It appears in Salesforce the next time it's updated (for example, after AWS accepts it or you manually edit something). Put the Salesforce opportunity's ID into the **Partner CRM Unique Identifier** field, and the system will make it show up in Salesforce and associate them together. ### The engagement score shows on the Salesforce referral. Can it also show on the opportunity screen? Yes, but this must be done in your Salesforce instance. ### Does the Fours–Salesforce integration handle public offer invoices? Yes. Fours supports auto-backfilling for Salesforce based on public offers, so when new customers purchase on AWS, that data flows to Salesforce. ### How do we sign up for and use the testing environment? You can create a testing environment connected to your sandbox environments within Fours. Once your Fours account is set up, you can add an additional environment associated with it. ## Fours Console: Other Topics ### What does integrating our solution with Fours look like, and what are the requirements? Connect your product registration page to Fours' webhook — see the [webhook guide](/settings/webhook/). Once connected, update the fulfillment URL of your AWS product to your SaaS registration page through Fours — see [Signup URL Redirect](/settings/signup-url-redirect/). ### Can I export the entitlement page to a CSV? Yes. Entitlements are one of sixteen exportable tables. Export runs from **Settings → Data Export** rather than from the entitlement page itself, as a one-time download or on a schedule, in CSV, JSON, or Parquet. See [Table Export](/settings/table-export/) for the formats and destinations available. ### In Fours, what's the difference between the Invoiced and Collectable amounts? The **Invoiced** value is the amount your customer was invoiced. The **Collectable** amount is what AWS will pay you once fees are deducted. --- Source: https://doc.fours.com/get-started/ # Get Started Fours is a cloud go-to-market platform for selling and billing software through AWS, Microsoft, Google Cloud, Snowflake, Alibaba Cloud, and Oracle marketplaces. This section is the onboarding path for a team that is new to Fours: create your organization and get it approved, connect the cloud you sell through, find your way around the console, and know how long each marketplace takes before you can sell. Work through **Start here** in order if you are setting Fours up for the first time — Quick Start walks the path from signup to your first offer in about 30 minutes of hands-on work, with two waits you don't control: Fours approving your organization, and the cloud provider reviewing a new marketplace listing. Once you are set up, the concepts, the everyday console screens, and your organization's settings each have a section of their own, listed under **Where to go next**. ## Start here 1. **[Quick Start](/get-started/quick-start/)** — sign up, get approved, connect a cloud, create your first product and offer; ~30 minutes hands-on, plus the approval and listing-review waits. 2. **[Account](/get-started/account/)** — create your organization, turn on MFA, and invite your team with the right roles. 3. **[Connect Your First Cloud Marketplace](/get-started/connect-your-marketplace/)** — link the cloud you sell through so you can list products, create offers, and get paid. 4. **[Navigate the Fours Console](/get-started/navigate-console/)** — find your way around the left navigation and the top-bar tools. ## Decide and plan - **[What Is Fours](/get-started/what-is-suger/)** — what the platform does and which marketplaces it covers. - **[Integration Timeline](/get-started/integration-timeline/)** — how long listing takes on AWS, Azure, and GCP; a net-new AWS listing runs about three weeks. ## Get unstuck - **[FAQ](/get-started/faq/)** — the questions that come up in practice: AWS payments and tax, private offers and CPPO, listing changes, the client sign-up page, and the Salesforce and HubSpot integrations. ## Where to go next - **[Concepts](/concepts/)** — the vocabulary the rest of the documentation assumes: what a cloud marketplace is, products, offers, entitlements, and buyers, the two money flows, how a deal runs, cloud commit drawdown, and the glossary. - **[Console](/console/)** — the screens you work in every day: the Home dashboard, your product catalog, private offers, customer companies, and contacts. - **[Settings](/settings/)** — email notifications, files, table exports, CRM-to-offer field mapping, the buyer signup redirect, API access, webhooks, and service quotas. - **[Metering](/metering/)** — report metered usage to each marketplace from the API, the console, or a billing platform, and grant usage credits. - **[Billing](/billing/)** — meter, price, invoice, and collect payment from the customers you sell to. - **[Workflow](/workflow/)** — automate operations with triggers, logic, and integration nodes, without writing code. - **[Fours AI Billing](/insulin/billing/)** — what *you* pay Fours for AI features: what is metered, the monthly free credit, and your own spending limit. ## Pick the marketplace you sell through Listing, offers, and revenue are cloud-specific. - **[AWS Marketplace](/aws-marketplace/)** — the broadest channel, with the most decisions to make up front: product type, a pricing model AWS locks at publication, and a review of your buyer experience. - **[Azure Marketplace](/azure-marketplace/)** — everything runs through Microsoft Partner Center, so the gating step is on Microsoft's side, and the vocabulary shifts: what Microsoft calls an offer is what Fours calls a product. - **[Google Cloud Marketplace](/gcp-marketplace/)** — the longest run-up: Partner Network enrollment, vendor approval and solution validation first, then listing approval in phases. - **[Snowflake Marketplace](/snowflake-marketplace/)** — you sell a data product or application to consumers identified by Snowflake account, and a provider profile must exist before any paid listing. - **[Alibaba Cloud Marketplace](/alibaba-marketplace/)** — one integration covers both the China and international markets, and you publish on Alibaba while Fours imports the product and runs the transactions. - **[Oracle Cloud Marketplace](/oracle-marketplace/)** — the narrowest: published SaaS listings sync in hourly, and offers are a one-time contract value sent to a buyer's tenancy. ## Scope and limits :::info This section covers getting set up on the Fours platform itself, not the per-cloud listing steps — those live in the marketplace sections above. Fours applies [service quotas](/settings/quota/) to how many resources you can provision, so a large migration may need an increase before it fits. ::: --- Source: https://doc.fours.com/billing/overview/ # Overview Quick guide to how billing works in Fours — from creating a product to tracking the money that lands in your account. --- ## Overview Fours gives you one place to manage the full billing lifecycle: create products, send offers, meter usage, invoice buyers, and track revenue across every cloud marketplace. How you get paid depends on how the deal is sold: - **Selling through your own Stripe account (as-buyer flow)** — Fours uses Stripe to invoice your customer and collect payment directly. Follow the [Billing workflow](#billing-workflow) below. - **Selling through a cloud marketplace (AWS, Azure, GCP, and others)** — the marketplace bills the buyer, collects payment, and sends you your share. Fours does not move the money; it consolidates the numbers so you can see what is happening. See [How marketplace revenue flows through Fours](#how-marketplace-revenue-flows-through-fours). ## Billing workflow ### 1. Create product Create a product to represent your sellable product or service. When create the product, select Stripe as partner because Fours will use Stripe to collect payments. Create product form with Stripe selected as partner ### 2. Define billable metrics If you want to use usage based pricing, you need to define the [billable metrics](https://doc.fours.com/billing/billable-metrics/) for the product you created in the previous step. They will be used in price models when creating offers and reporting usage data. ### 3. Create buyer Create a [buyer](https://doc.fours.com/billing/buyer/) to represent your customer. You can set the billing address, currency, and other information for the buyer. ### 4. Create and send offer Create a [offer](https://doc.fours.com/billing/offer/) including price models and send it to your customer. You can configure the contract duration, billing interval, flat fee, and usage metering and other details in the offer. Send the offer to your customer, if the customer accepts the offer, a entitlement will be created. ### 5. Manage entitlement You can view the [entitlement](https://doc.fours.com/billing/entitlement/) just created, track the usage and billing status. Edit or cancel it when needed. ### 6. Report usage data Report [usage metering](/metering/) data to Fours using the API or SDK. Fours will aggregate the usage data periodically which will be used to calculate the charges. ### 7. Invoicing [Invoices](https://doc.fours.com/billing/invoice/) will be generated automatically for each entitlement according to price models in it. There are several types of invoices including installments, recurring commitments, usage based and one-time. ### 8. Payments Fours will process [payments](https://doc.fours.com/billing/payment/) automatically to collect money from the buyer via Stripe when the invoice is due. The money collected will be deposited to your Stripe account. ### 9. Revenue [Revenue reports](https://doc.fours.com/billing/revenue/) will be generated for each entitlement and also aggregated by product and buyer. ## How marketplace revenue flows through Fours When a buyer accepts your offer through a cloud marketplace, your deal becomes active and the revenue process starts. At this point you are not getting paid yet — first the marketplace has to bill the buyer, collect payment, and then send you your share. Once a deal is accepted, it becomes an active contract (an **entitlement** in Fours). From here, **Fours does not handle payments**. The cloud marketplace bills the buyer and collects the money. Fours' job is to show you what is happening with your revenue in one place. ### If you charge based on usage If your product uses usage-based pricing (API calls, storage, active users, and so on), the marketplace needs usage data before it can generate an invoice. Without it, there is nothing to bill. You can send usage data to Fours in three ways: - **Billing engine integration** — connect Fours to your internal billing tool (such as Metronome, Orb, Lago, or Chargebee) and usage is reported automatically. - **Fours API** — your engineering team calls the [Fours Metering API](/metering/) directly to push usage records programmatically. - **CSV upload** — your billing or operations team manually uploads a CSV file in the Fours Console. For more information, see [Metering](/metering/). Fours collects this data, cleans it up, and sends the final numbers to the cloud marketplace so it can generate the invoice. ### When will I get paid? Once the contract is active (and usage is sent, if needed), payment moves through three phases. **Phase 1: Invoice is created (invoice date).** The marketplace issues the invoice to the buyer, based on the entitlement's payment schedule. The invoice date is the start of the billing cycle, **not** the payout date. **Phase 2: Buyer pays the cloud provider (due date).** The buyer pays based on their payment terms with the cloud provider (for example Net 30, Net 60, or Net 90). This is not the same as the invoice issue date — the invoice may be issued on one date, but the buyer may only be required to pay 30–90 days later. **Phase 3: You get paid (disbursement date).** After payment is collected, the marketplace deducts its fee and sends you the remaining amount as a single payout. This happens only after the buyer has paid the invoice and the marketplace has completed its processing window. To check your payment schedule, go to **Revenue** → [**Joined Records**](https://console.suger.io/revenue/joined-records) and review the **Invoice Date**, **Due Date**, and **Disburse Date** columns. ![Joined Records showing invoice, due, and disburse dates](images/how-marketplace-revenue-flows-through-su-1.png) ### Find and track your revenue The **Revenue** tab in the Fours Console is your consolidated financial ledger across all cloud marketplaces. It aggregates all invoice-level data tied to your active entitlements. At the top of the Revenue tab you can toggle between two views: - **Joined Records** — the default view. It stitches together all billing events (invoices, taxes, fees, and disbursements) into one clean line item per transaction. This is where most teams work day to day. - **Raw Records** — shows unfiltered financial data exactly as it comes from the cloud provider's billing system. Use this for deep auditing or line-item reconciliation. For more details on tracking revenue, see [Revenue](https://doc.fours.com/billing/revenue/). ### Reconcile marketplace revenue with your accounting system Marketplace payouts usually arrive as a single deposit that covers multiple invoices, customers, and transactions. That makes it hard to match what landed in your bank account with the revenue recorded in your accounting system. Fours helps by providing a detailed breakdown of every invoice, fee, tax, and disbursement associated with a marketplace transaction. Your finance team can: - Review transaction details in the **Revenue** tab - Export revenue data for month-end reconciliation - Sync marketplace revenue directly into supported ERP systems :::tip If your team uses NetSuite or QuickBooks, Fours can automatically map marketplace transactions into your accounting workflow. This includes breaking down lump-sum marketplace payouts into individual customer transactions and preventing duplicate invoicing when the marketplace is already billing the buyer. ::: --- Source: https://doc.fours.com/billing/billable-metrics/ # Billable Metrics Define metrics to track usage and consumption. --- The Billable Metrics are used to define the goals and aggregation type of metering. You can define the metrics according to your business needs, such as the number of API calls, the amount of storage, the number of users, etc. Billable metrics are the master templates for what you measure. Before you can report usage to AWS, Azure, or GCP, you must define the unit of measurement within Fours. ## Create billable metric You can create a new billable metric on the [**Usage Metering > Settings**](https://console.suger.io/metering?tab=settings) tab. They should be created before creating the offer which contains a usage-based price model. 1. **Navigate to Settings**: In the Fours Console, go to [**Usage Metering > Settings**](https://console.suger.io/metering?tab=settings). 2. **Add Metric**: Click the **+ Add billable metric** button. 3. **Configure the basic information** and rules described below. 4. Click **Create**. > Usage Metering settings page showing billable metrics list Create billable metric dialog with basic information fields ![Add billable metric form in Usage Metering settings](images/configure-usage-metering-settings-1.png) A billable metric is defined by the following properties: - **ID**: Used to report usage records. It should be unique in your organization, and must match the ID used in your API calls or CSV uploads. - **Name**: Display name that your team can easily identify. - **Description**: (Optional) Context regarding what this metric measures for future reference. - **Filter Groups**: Criteria to filter the reported usage data. - **Aggregation Type**: How to aggregate the reported usage data. - **Property Unique On**: Used for distinct counting when the aggregation type is UNIQUE COUNT. - **Group By**: Used to divide usage data into different groups by properties. Each group will be billed separately. ## Filter groups `Filter Groups` are used to filter usage records you reported, only those meet the filtering criteria will participate in the aggregation. Filter groups configuration for a billable metric - Different groups have an "AND" relationship, while the filters within each group have an "OR" relationship. - Each Filter expression left side is a Property name carried when reporting Usage Records, and the right side is the target value. - Filter operators for string properties: `is`, `not is`, `contains`, `not contains`, `exists`, `not exists`. - Filter operators for numeric properties: `greater than`, `greater than equal`, `less than`, `less than equal`, `equal`, `not equal`. ## Aggregation types How the reported usage data will be aggregated before calculating the fee. Fours supports the following aggregation types: | Aggregation Type | Description | | ---------------- | --------------------------------------------------------------------- | | COUNT | The count of usage records reported. | | UNIQUE COUNT | The distinct count of usage records reported on a specified property. | | SUM | The total sum of the quantity values from usage records. | | MAX | The maximum value of the quantity value from usage records. | | LATEST | The latest value of the quantity value from usage records reported. | ## Property unique on When selecting `UNIQUE COUNT` as the aggregation type, you need to specify the property to count. And the usage data you reported should contains the specified property. > Property unique on field for UNIQUE COUNT aggregation ## Group By `Group By` will divide usage records reported into different groups according to the specified dimensions. When reporting usage data, the specified dimensions should be used as keys in the properties field of usage records. :::info - Each group will be calculated separately by price model. - Currently, a maximum of `3` dimensions are supported for group by. ::: In the below example, we choose `partner` and `region` as the group by dimensions, if property `partner` in our usage data has the following values: `aws`, `azure`, `gcp`, and property `region` has the following values: `us-east`, `eu-west`, then the usage data will be divided into 6 groups. > Group by partner and region dimensions example ## Configure partner-specific settings Once a metric is defined, you must tell Fours how that metric interacts with a specific cloud partner. Each marketplace has unique rules for how usage is aggregated and billed. | Setting | Operational purpose | | --- | --- | | Commit With Additional Usage | When enabled, you can bill for "overages" even if a buyer has a fixed-price contract (commit). | | Commit With List Price | Determines whether additional usage is billed at your custom negotiated rate or the standard marketplace list price. | | Dimension Mapping | Maps your internal billable metric ID to the specific dimension ID defined in your marketplace product listing. You must enable this for usage to be reported to the partner. | ## The pricing dimension rule Usage metering only functions if the underlying product listing supports it. Fours generates the marketplace invoice using this calculation: **Usage Amount = Quantity Reported × Dimension Unit Price** - **Requirement**: If your product listing in the marketplace (AWS/GCP/Azure) was built as "commit-only" (fixed price) without usage pricing dimensions, usage **cannot** be reported. - **Verification**: If usage options are missing from an entitlement, check that the listing includes the necessary dimensions. If you add a new dimension to a listing, you must **Refresh** the product in the Fours Console to sync the changes. ## Troubleshooting Usage metering is technically complex and direct changes can have immediate financial consequences. Work through the checklist below before making changes. - **Inactive configs**: Ensure the **Dimension Mapping** status is **Enabled** for the specific partner (for example, AWS) you are currently billing. - **ID mismatch**: Verify that the **Billable Metric ID** in Fours matches the external ID expected by your metering provider or your manual CSV headers. - **Sync issues**: If a dimension was recently added to the marketplace, refresh the product in Fours so the dimension appears in your metering configs. :::warning If questions arise regarding usage discrepancies, contact Fours Support or your Customer Success Manager rather than making ad-hoc changes to the mapping configuration. ::: ## Edit billable metric Most parts of the billable metric's information can not be edited because they may be already used. You can archive a billable metric if you don't need it anymore. --- Source: https://doc.fours.com/billing/price-model/ # Price Model Define how the buyer will be charged. --- ## Overview There are 2 types of price models can be configured in the offer: - **Flat fee**: A fixed amount charged for the offer, which can be configured as installments or recurring commits. - **Usage metering**: A usage-based pricing model that charges the buyer based on the actual usage of metrics. **Billing period** The price model will be applied to the contract and the buyer will be charged peroidlly in the entire contract duration, each period is called a billing period. **Billing cycle** The start day of the billing period, which can be the start day of the entitlement or the 1st day of the month. **Billing interval** The billing frequency, such as monthly, quarterly, annually, etc. ## Flat fee ### Installments It's very flexible to use installments to charge the buyer. You can configure a series of installments and each installment consists of amount and payment date, which like a payment schedule. Installment payment schedule configuration for an offer ### Recurring commits If you want to charge the buyer in a fixed amount per period, use the recurring commits. A recurring commit should have name, quantity and rate. The total amount is calculated as `quantity * rate`. You can add multiple recurring commits in the offer. Recurring commit configuration with name, quantity, and rate **Prepay or postpay** You can choose to charge the buyer in advance or in arrears for the recurring commits. **Update commit quantity** You can update the commit quantity during the contract. Which is useful in the `Per-Seat` offer scenario, for example, the buyer may want to increase/decrease the number of seats during the contract. ## Usage metering In addition to the flat fee, you can also charge the buyer based on the actual usage. **Billable dimension** A billable metric and how it is charged makes up a billable dimension, you can configure multiple billable dimensions in the offer. Billable dimension configuration in the offer ### Usage metering price model The way to charge the metric is called usage metering price model, Fours supports the following 7 types price models: - Basic pricing - Tiered pricing - Bulk pricing - Volume pricing - Percentage pricing - Tiered percentage pricing - Matrix pricing **Basic pricing** In a basic price model, each unit of a Billable Metric is assigned a fixed cost. Basic pricing price model configuration Example: Consider a company offering cloud storage services at a rate of $0.5 per gigabyte (GB). In this scenario, the `per unit` is set to $0.5 for Billable Metric "per gigabyte", indicating that each GB costs $0.5. For 10 units, `10 x 0.5(unit amount) = 5`, $5 in total. **Tiered pricing** In tiered pricing, the cost of a given unit depends on the tier range that it falls into, defined by upper and lower bounds. For example, the first 5 GB costs $0.5 each with $10 flat fee, 6-10 GB costs $0.3 each with $5 flat fee, and all subsequent GBs cost $0.2 each with no flat fee. Tiered pricing price model configuration Example: 1. For 4 units: - Calculated as `4 x 0.5 + 10 = 12`, $12 in total. 2. For 8 units: - Calculated as `(5 x 0.5 + 10) + (3 x 0.3 + 5) = 18.8`, $18.8 in total. 3. For 15 units: - Calculated as `(5 x 0.5 + 10) + (5 * 0.3 + 5) + (5 * 0.2) = 20`, $20 in total. **Bulk pricing** With bulk pricing, units are charged in fixed bundles (referred to as bulk sizes). For instance, if the bulk size is set to 5: - Purchasing 4 units will be billed as a bundle of 5. - Purchasing 6 units will be billed as 2 bundles of 5. Bulk pricing price model configuration Example: 1. For 4 units: - Calculated as 1 bulk (5 units) × $5 = $5 total. 2. For 6 units: - Calculated as 2 bulks (10 units) × $5 = $10 total. **Volume pricing** In volume pricing, the total number of units purchased determines the cost per unit for all units. Volume pricing price model configuration Example: 1. If you purchase 8 units, the total cost is calculated as: - `8 * 0.5 (unit price) + 5 (flat fee) = $9` in total. 2. If you purchase 15 units (more than 10), the total cost is calculated as: - `15 * 0.4 (unit price) + 0 (flat fee) = $6` in total. **Percentage pricing** Percentage pricing applies a rate per event based on a percentage of the value in the event. For example, for a payment event, it is calculated as a percentage of the transaction value. Percentage pricing price model configuration Example: 1. For a transaction of $100, the total charge is calculated as: - `100 * 0.25 (percentage rate) + 3 (flat fee) = $28` in total. **Tiered percentage pricing** Tiered percentage pricing applies a per event rate based on a percentage of the value in the event., with different rates for specified tiers. Example: If the pricing is set as follows: Tiered percentage pricing price model configuration 1. For a payment of 9 units, Calculation: - `9 * 0.25 (percentage rate) + 3 (flat fee) = $5.25` in total. 2. For a payment of 20 units, Calculation: - `10 * 0.25 (percentage rate) + 3 (flat fee) + 10 * 0.20(percentage rate) + 1 (flat fee) = $8.50` in total. **Matrix pricing** Matrix pricing determines the cost based on combinations of two or more properties. Example: If the pricing is set as follows: Matrix pricing price model configuration The pricing config can be represented in the following table: | Group | Property 1 | Property 2 | Price per Unit ($) | | ------- | ------------- | ------------- | ------------------ | | 1 | partner = aws | region = east | $1.00 | | 2 | partner = gcp | - | $0.80 | | default | - | - | $0.50 | All reported data will be grouped by the property combinations, and the price will be calculated based on the group. If no group matches, the default price will be applied. ### Minimum spend You can set a minimum spend for the billable dimension, if the total amount of the billable dimension is less than the minimum spend, the buyer will be charged the minimum spend for this billable dimension. ### Discount You can set a discount for the billable dimension, which will be applied to the billable dimension amount before calculating the total amount. ## Trial period You can set the trial period for the offer to give the buyer a free trial. - The recurring commit fee will be prorated by the trial days. - The usage will be ignored and not charged during the trial period. ## Common pricing solutions ### Good-better-best offer The good-better-best offer or tiered offer is a common SaaS offer solution, it provides a basic package and then offers more features in higher tiers. For example, Wix provides 4 tiers of offers, each tier has different features and price. Wix good-better-best tiered offer example When we create this type of offer, add different recurring commits to represent the tiers, no need to configure the usage metering. Recurring commits configured to represent good-better-best tiers Second recurring commit tier configuration example ### Per-seat offer Many products charge the buyer based on the number of users or seats, and the seats can be increased or decreased during the contract. For example, Clickup bills per user per month. ClickUp per-seat per-month pricing example When we create this type of offer, add a recurring commit to hold the seat quantity and rate, the rate can also be different according to different tiers. Recurring commit configured for seat quantity and rate Per-seat recurring commit tier rate example ### Pay-as-you-go offer For example, Google cloud offers pay-as-you-go service for there product BigQuery, the buyer will be charged based on the actual storage usage. Google Cloud BigQuery pay-as-you-go pricing example When we create this type of offer, define different storage types as billable metrics, and configure them in the usage metering billable dimensions. ### Fixed-fee and usage-based combination offer We can use recurring commits and usage metering together to charge the buyer very flexibly. Scenario 1: You can add a recurring commit fee for a package of some quantities of several billable metrics, and configure each billable metric's price model to handle the overage quantity. Then any metric's usage over the quantity will be charged. Scenario 2: You can add a recurring commit fee as basic charge, and configure each billable metric's price model normally. If the total amount of usage metering is over the commit, you will charge the buyer the overage. ## Currency display Amounts are rendered with the currency's own symbol where Fours has one, and with the bare ISO code otherwise: | Currency | Symbol | | -------- | ------ | | AUD | `A$` | | CAD | `CA$` | | CNY | `CN¥` | | EUR | `€` | | GBP | `£` | | JPY | `JP¥` | | USD | `$` | Anything else shows its ISO code, which is accurate rather than approximate — a wrong symbol is worse than no symbol. A **discount stated as an absolute amount** on a usage line is prefixed with the invoice's own currency symbol rather than a hard-coded `$`, so a EUR invoice no longer describes its discount in dollars. --- Source: https://doc.fours.com/billing/buyer/ # Buyer Buyer management. --- When using Fours' metering and billing service, you'll need to create a buyer profile for your customer. This differs from marketplace connections, where buyer profiles are managed by the marketplace. Before creating a buyer, ensure you have connected to a billing integration - currently, Stripe is the supported integration platform. ## Manage buyer ### Create buyer Enter the buyer's basic and company information. Create buyer form with basic and company information #### Choose a partner Select a partner for the buyer. Currently, only Stripe is supported. :::tip - The partner cannot be changed after the buyer is created. - If you need to connect a customer to multiple partners, you need to create multiple buyers on Fours. ::: #### Integration information - Customer ID: The customer ID from your internal system. - Stripe Customer ID: If this buyer already exists in Stripe, Fours will connect the buyer to the Stripe customer. Otherwise, Fours will create a new customer in Stripe for this buyer. Buyer integration fields for Customer ID and Stripe Customer ID #### Payment configuation Set the buyer’s payment configuration: 1. Select Currency: Choose the currency the buyer will use for payments. Currently supported currencies: USD, EUR, GBP. 2. Allowed Payment Methods: Choose the payment methods based on the currency. - Different currencies support different payment methods. For example, with USD, ACH Debit (US Bank Account) is available. If not selected, the buyer cannot use ACH Debit. - Cards are always enabled by default. - Credit can also be enabled (details below). | Currency | Allowed payment methods | | :------- | :---------------------------------------- | | USD | Card, ACH Debit (US Bank Account), Credit | | EUR | Card, SEPA Debit, Credit | | GBP | Card, BACS Debit, Credit | ### Edit buyer Open the buyer from **Companies** and click its **Edit** action, or open its company page and choose **More actions** → **Edit info**. Every buyer on the Companies page, including buyers that come from a cloud marketplace, is edited in the same **Edit Buyer** panel. Most of the buyer's information can be modified, except for: - Partner - Stripe Customer ID - Currency The panel's optional **Integration Information** section links the buyer to its record in your other systems: | Field | What it links | | :---- | :------------ | | Stripe customer ID | The buyer's customer in Stripe. It can't be changed for a buyer whose partner is Stripe. | | Chargebee customer ID | The buyer's customer in Chargebee. Fours' hourly Chargebee usage sync picks up only buyers that carry one, and reports that Chargebee customer's priced overage as usage on the buyer's entitlement. See [Connect Chargebee Customer](/integrations/chargebee/#connect-chargebee-customer). | | Metronome customer ID | The buyer's customer in Metronome, for usage metering. | | Orb customer ID | The buyer's customer in Orb, for usage metering. | | Lago customer ID | The buyer's customer in Lago, for usage metering. | | Customer ID | The buyer's ID in your own system. It can identify the buyer in a CSV of usage you batch-report. | ### Share buyer portal Fours generates a dedicated buyer portal for each buyer. To get its URL, open the buyer's company page (**Company** in the console navigation — see [Companies](/console/company/)), select **More actions**, then choose **Share buyer portal**. The portal opens in a new tab; copy its URL and share it with the buyer. Buyer portal url will be in the format `https://console.suger.io/spa/buyer?token=xxx` Buyer portal URL on the buyer detail page Buyers can view their offers, entitlements, invoices, and manage payment methods on this portal. Buyer portal with offers, entitlements, and invoices :::warning - This page does not require buyer to login. The URL will contain a one-time authentication token with a limited validity period. Buyers can access the portal within this timeframe. - Don't share the URL with unauthorized buyers. ::: ## Manage wallet After the buyer is created, you can help to set up payment methods to ensure automatic invoice payments in the future. ### Stripe payment method For buyers who's partner is Stripe, payments are processed through Stripe. Fours supports the following payment methods through Stripe: - Card (all currencies) - SEPA Debit (EUR only) - BACS Debit (GBP only) Learn more: [Stripe Documentation](https://docs.stripe.com/payments/payment-methods/overview) :::tip If you need to add a test payment method, you need to connect Fours to your Stripe test account when creating the integration. Learn more: [Create Stripe Integration](https://doc.fours.com/integrations/stripe/) ::: #### Add new payment method Fours uses the Stripe SDK to securely collect payment method details. These details will be stored in Stripe to process payments in the future, you only need to add the payment method once. Learn more: [Stripe Documentation](https://docs.stripe.com/payments/payment-element) :::tip Sensitive card information will not be stored in Fours. :::
Click here to see the details about payment method collection. Payment method collection dialog using Stripe SDK
- **Add card** Adding a card is straightforward, but some cards may not be eligible for addition due to restrictions. Add new card form for a buyer - **Add a US Bank Account** Adding a bank account is a little more complex. Stripe guides the user through the bank-linking process. Add US bank account step 1 of Stripe bank-linking Add US bank account step 2 of Stripe bank-linking #### Set default payment method You can set a payment method as default, Fours will use this method first for invoice payments. #### Delete payment method Payment methods can be deleted but cannot be modified. ### Credit Credits are managed by Fours. You can assign some credits to a buyer to pay for their invoices. Credits are currency-specific and works like a wallet balance. #### Create credit Each credit can have its own active period. Create credit form with active period #### Close credit You can close a credit before its active period ends. Once closed, the credit will be unusable. #### Credit use and refund - Credits within their validity period are automatically applied during invoice payments. - Credits can be deducted multiple times, but the total usage cannot exceed their original amount. - Multiple credits can be used for a single invoice payment. - Credits can be refunded, and the corresponding amount will be restored. --- Source: https://doc.fours.com/billing/offer/ # Offer Operations on offers. --- ## Create offer ### Configure offer basic information - Select the product and buyer, enter the offer name. - Specify the contract start date, end date, and offer expiry date. - If you don't specify the start date, the contract will start at the day of offer acceptance. Product, buyer, and offer name fields when creating an offer Contract start, end, and expiry date fields when creating an offer ### Configure offer flat fee - **Billing cycle**: Select billing cycle, either `1st day of the month` or `Entitlement start day`. - **Billing interval**: You can set the billing interval for the recurring commits and usage metering, which will generate an invoice for each interval. - **Payment installments**: Configure multiple payment installments, specifying the charge date and amount for each. - **Recurring commits**: You can configure multiple recurring commits, each with a key, quantity, and rate. The commit amount is calculated as `quantity x rate` for each commit. Each commit will be listed as an item on the invoice. - **Recurring payment schedule**: You can choose to pay in advance or pay in arrears, meaning invoices will be generated at the start or end of an interval. Payment installments configuration with charge date and amount Recurring commits configuration with key, quantity, and rate ### Configure offer usage metering Define the usage-based fee for the offer by setting up billable dimensions. Each billable dimension consists of a billable metric and a usage metering price model. For further information about [how price model works](./2.price-model.md#usage-metering-price-model). - **Billable metric**: Select the metric you want to use for billing. - **Price model**: The usage metering pricing model determines how the cost of a billable metric is calculated. - **Minimum spend**: You can set a minimum spend for the given billable metric. - **Discount off**: You can set up a discount for the given billable metric, either as a percentage or a fixed amount. Usage metering billable dimension configuration for an offer ### Configure leagal term and invoice settings - **Net terms**: The number of days within which the customer must make a payment. - **Grace period**: The period during which invoices remain in draft status for review or editing. After this period, the invoice is finalized and cannot be modified. - **Trial period**: You can set a trial period in days. The customer will not be charged during this period. - **EULA**: Optionally, you can add a custom End User License Agreement (EULA) for the private offer. - **Auto renew**: Automatically renew the entitlement term once the current entitlement ends. Net terms, grace period, trial period, and EULA settings for an offer ### Preview offer Preview the offer details before creating it. Additionally, you can choose to save the offer as a draft and edit it later. Offer preview page before creation ## Accept offer ### Send offer to buyer Once an offer is created, you can send the offer link to the buyer. The offer link contains a token to identify the offer. The offer link will expire after the offer expiry date. ### Accept offer When the buyer receives the offer link, they can check the offer details and accept it. - The buyer can add payment methods in this page. - Once the offer is accepted, an entitlement will be generated based on the offer. - If the offer has recurring commits and the recurring payment schedule is `Prepay`, the invoice will be generated and the buyer will be charged immediately after accepting the offer. Public offer acceptance page with payment method entry ## Check if a private offer has been viewed You can track whether a customer has received and viewed a private offer, and notify them again if needed. 1. Open the **Offers** tab from the main dashboard. 2. Locate and select the specific private offer you want to check. 3. In the first card at the top, click the **Contacts** button. 4. The **Contacts** section shows the contacts you've already sent notifications to, along with notification events indicating which contacts have opened the email. 5. To notify a customer again, click the **Notify** button next to their contact information. This sends another notification to that contact. 6. You can also add existing contacts or create new contacts to notify about this private offer, expanding the reach of your offer. ## Offer actions You can perform some actions on the offer details page. Available actions on the offer details page ### Cancel offer You can cancel the offer anytime before the buyer accepts it. ### Extend offer expiry date If the offer is about to expire, you can manually extend its expiry date. --- Source: https://doc.fours.com/billing/entitlement/ # Entitlement An entitlement is the active, accepted contract that proves a customer has purchased your product and is entitled to use it. --- ## Overview In cloud marketplaces, an entitlement (also known as an agreement) represents an active, accepted contract. While a private offer defines the terms you propose to a buyer, the entitlement is what becomes active after acceptance and drives billing and revenue. | Feature | Private offer | Entitlement | | --- | --- | --- | | Definition | Proposed commercial terms sent to a buyer | The finalized agreement and usage rights granted after acceptance | | Creation | Manually created by sales or deal desk | Automatically created by the system | | Purpose | Deal negotiation | Active contract tracking and billing | Use the entitlement record whenever you need to know whether a deal is active, when the contract ends, or when you will get paid. ### How an entitlement is created Entitlements are never created manually in Fours. They are generated automatically whenever a customer successfully purchases or accepts an offer through a cloud marketplace. This can happen through either a public offer or a private offer. **Public offer flow** 1. **Marketplace listing published** — Your product is available as a public marketplace listing. 2. **Buyer purchases** — A buyer self-serves and subscribes directly through the marketplace. 3. **Marketplace processing** — The cloud marketplace confirms the transaction and activates the agreement. 4. **Active entitlement generated** — Fours automatically creates an active entitlement in your console and CRM. **Private offer flow** 1. **Private offer sent** — Your team generates and extends a private offer to the buyer's cloud account. 2. **Buyer accepts** — The buyer logs into their marketplace portal and accepts the offer. 3. **Marketplace processing** — The cloud marketplace confirms the transaction and validates the payment terms. 4. **Active entitlement generated** — Fours automatically creates an active entitlement in your console and CRM. ### How teams use entitlements Each entitlement is linked to a CRM opportunity, private offer, product, and buyer account, making it the shared record across Sales, Customer Success, and Finance. - **Sales tracking** — Sales teams use entitlements to confirm when a deal is closed. When a buyer accepts a private offer, an entitlement is created and the CRM opportunity is automatically marked as **Closed Won**. - **Customer Success provisioning** — Customer Success teams use entitlements to understand what the customer purchased and when it becomes active. - **Finance reconciliation** — Finance teams use entitlements to connect revenue back to the original deal. ## Terminate an entitlement You can schedule a cancellation of an entitlement. There are three cancellation types supported: - Immediate: The entitlement will be terminated immediately. - End of Term: The entitlement will be terminated at the end of current term. - Specific Date: The entitlement will be terminated at a specific date. > Entitlement cancellation type selection dialog > Entitlement termination date scheduling When an entitlement terminates, Fours will automatically calculate charges for any outstanding usage and generate the final invoice. For commitment charging terms: - If the payment schedule is `postpay`, a final invoice will be generated with the prorated days. - If the payment schedule is `prepay`, a refund will be made for the unused period. ## Apply an Addon You can apply an addon to an entitlement if you need to charge the customer an additional amount. > Apply an addon to an entitlement dialog ## Alert before the end date of an entitlement Sellers can configure the `alertDaysBeforeEnd` field in the entitlement configuration to send an alert to both the seller and the customer before the end date of an entitlement. The `alertDaysBeforeEnd` field can be set to 15 or 45 days. ## Auto-renew an entitlement Sellers can configure the `autoRenew` field in the entitlement configuration to automatically renew the entitlement at the end date. The `autoRenew` field can be set to either `true` or `false`. - If set to `true`, the entitlement will be automatically renewed at the end date. - If set to `false`, the entitlement will not be automatically renewed. --- Source: https://doc.fours.com/billing/invoice/ # Invoice Effortless invoice management. --- ## Overview For Non-Cloud Partners (e.g. Stripe, Adyen), Fours automatically generates and issues invoices based on the entitlement. You can easily manage your invoices with the Fours Console. ## Manage Your Invoices ### View Invoices Invoices can be viewed on the **Invoices** tab of the entitlement detail page or of the buyer's company page. Both tabs show the multi-channel accounts-receivable view from [Revenue → Invoices](/revenue/invoices/), narrowed to that entitlement or company and covering all time by default. Click **View Details** on an invoice to see its billing and settlement detail — refund, write-off, and dunning details are not currently filled in (see [Invoices](/revenue/invoices/)): > Invoice list table on the entitlement detail page The invoice's own page, where you edit, issue, send, export, or cancel it (see below), opens from its invoice ID in a buyer's payment transactions — on the buyer's company page, open the **Revenue** tab and select **Raw Records**: > Invoice detail page ### Edit a Draft Invoice You can edit a **Draft** invoice by clicking **Edit** button on the invoice detail page. > Edit button on a draft invoice detail page The following changes are supported: - Due date: The due date when the invoice will be paid. - Discount: The overall discount applied to the total amount of the invoice. There are 2 discount options: - **USD**: The discount is a fixed amount. - **%**: The discount is calculated as a percentage of the total amount. - Note: The memo that will be visible to buyers and shown on the official invoice page. ### Issue an Invoice #### Automatic Invoice Issuance Invoices are automatically issued to all the buyer’s contacts when the **issue date is due**. #### Manually Issuing an Invoice You can also manually issue a **Draft** invoice by clicking the Issue button on the invoice detail page. Steps to Issue an Invoice Manually: 1. Preview the invoice PDF and email content. 2. Select contacts to receive the invoice email (all contacts are selected by default). 3. Acknowledge by checking: “I understand that this invoice will be issued. This action CANNOT be reversed.” 4. Click **Send Invoice**—the invoice will be issued immediately, and the due date will be set to the current date. > Invoice PDF preview before issuing > Invoice email content preview before issuing ### Send an Invoice Email Once an invoice is issued, you can send the invoice email to specific contacts by clicking the **Send Invoice** button on the invoice detail page. ### Export an Invoice A **Finalized** invoice can be viewed and exported as a PDF document by clicking the **Export** button. > Exported invoice PDF document ### Cancel an Invoice You can cancel an invoice before its payment by clicking **More - Cancel invoice** on the invoice detail page. :::warning A **Canceled** invoice is **immutable**, meaning it cannot be edited or reissued. ::: **A canceled invoice owes nothing.** Canceling writes the amount due down to **0** on the invoice itself, and every read of an invalidated invoice reports 0 regardless of what residual balance its columns still carry. That applies to each of these statuses, in either the invoice status or the payment status: **VOID**, **VOIDED**, **CANCELED**, **CANCELLED**, **WRITTEN_OFF**. The match ignores case and treats spaces and hyphens as underscores, because provider-synced invoices store the provider's own spelling rather than Fours'. One consequence is visible on the page: **the Payment Transaction table disappears** once the amount due is 0. That is the same rule, not a separate behaviour — there is nothing left to collect, so there is no payment activity to show. This is deliberately one rule shared by the buyer portal, the console list, and the invoice API, so all three agree about a single invoice rather than each applying its own reading. ## Invoice ID Invoice ID is a stable unique identifier based on the organization ID, entitlement ID, dimension key, and invoice drafted time. ## Invoice Types There are four types of invoices: **Commit**, **Installment**, **Usage**, and **Addon**. Different types of invoices will be generated for different entitlement terms, meaning that one entitlement can include multiple invoices, each of a different type. For example, if an entitlement includes both **Commitment** and **Billable Dimension(s)** pricing terms, two invoices will be created: one for the **Commitment** and one for the **Billable Dimension(s)**. ### Commit Invoice For **Commitment(s)** pricing terms in the entitlement, **Commit** invoices will be created. > Commit invoice for commitment pricing terms ### Usage Invoice For **Billable Dimension(s)** pricing terms in the entitlement, **Usage** invoices will be created based on the usage record reports. > Usage invoice for billable dimension pricing terms Usage record reports are generated from Usage record groups reported by the seller on the **Usage Metering** section on the entitlement detail page: > Usage Metering section on the entitlement detail page ### Installment Invoice For **Payment installments** pricing terms in the entitlement, **Installment** invoices will be created. Installment invoice for payment installment terms ### Addon Invoice Fours enables sellers to charge additional fees to buyers by creating an addon invoice tied to the entitlement. Sellers can create an addon on "**Settings** - **Addon**" tab and apply an addon by clicking "**Apply Addon**" button on the entitlement detail page: > Apply Addon button on the entitlement detail page > Apply Addon dialog on the entitlement detail page ## Invoice Lifecycle The invoice lifecycle consists of the following stages: **Drafting**, **Issuing** and **Payment**. > Invoice lifecycle stages: Drafting, Issuing, and Payment ### Drafting An invoice will be automatically created based on its type and entitlement and enters the **DRAFT** status. Three important dates are involved in the drafting process: **Draft Date**, **Issue Date**, and **Due Date**. #### Draft Date The draft date differs from different invoice types: - **Commit**: draft date is computed as [below](#commit-invoice-period). - **Usage**: draft date is computed as [below](#usage-invoice-period). - **Installment**: draft date is the payment installment charge date. - **Addon**: draft date is its specified charge date. #### Issue Date Issue date is calculated as: `draft date + grace period`. For example, if the **draft date** is 2025-01-01, and the **grace period** is 7 days, the **issue date** will be 2025-01-08. #### Due Date Due date is calculated as: `issue date + net term days`. For example, if the **issue date** is 2025-01-08, and the **net term days** is 10 days, the **due date** will be 2025-01-18. ### Issuing When the invoice issue date is due or the invoice is manually issued, it transits into the **FINALIZED** status. Notifications emails will be sent to the buyer's contacts when the invoice is issued. ### Payment Payment transactions will be automatically made on the invoice due date. After the payment is completed, the invoice is marked as **PAID**. For details, see [Payment](https://doc.fours.com/billing/payment/). ### Canceling Once an invoice is canceled, it is marked as **CANCELED** status and will not proceed to payment. ## Invoice Period "Invoice period" answers the following questions: 1. When will an invoice be created? 2. What's the start date and end date of the invoice? Invoices periods are calculated based on different invoice types as follows. ### Commit invoice period The **Commit** invoice period varies depending on the following factors: 1. Entitlement's start date: `past` or `future`. If the entitlement start date is in the past, the first invoice may include multiple periods. If the entitlement start date does not cover the full billing period, the invoice will be prorated accordingly. 2. Billing cycle: `beginning of the month` or `start of the entitlement`. 3. Payment schedule type: `prepay` or `postpay` The first invoice period is determined as follows: | **Entitlement Start Date** | **Billing Cycle** | **Payment Schedule** | **First Invoice Start Date** | **First Invoice End Date** | **First Invoice Draft Date** | | -------------------------- | ---------------------------- | -------------------- | ---------------------------- | -------------------------------------------- | ---------------------------- | | **Past** | **Beginning of the Month** | **Prepay** | Entitlement's start date | Nearest first day of the month | Today | | **Past** | **Beginning of the Month** | **Postpay** | Entitlement's start date | Nearest first day of the month | Same as the end date | | **Past** | **Start of the Entitlement** | **Prepay** | Entitlement's start date | Entitlement's start date in the next period. | Today | | **Past** | **Start of the Entitlement** | **Postpay** | Entitlement's start date | Entitlement's start date in the next period. | Same as the end date | | **Future** | **Beginning of the Month** | **Prepay** | Entitlement's start date | Nearest first day of the month | Same as the start date | | **Future** | **Beginning of the Month** | **Postpay** | Entitlement's start date | Nearest first day of the month | Same as the end date | | **Future** | **Start of the Entitlement** | **Prepay** | Entitlement's start date | Entitlement's start date in the next period. | Same as the start date | | **Future** | **Start of the Entitlement** | **Postpay** | Entitlement's start date | Entitlement's start date in the next period. | Same as the end date | Below are the detailed scenarios for the invoice period. #### 1. Start date in the past If the Entitlement's start date is in the past, the entitlement is considered active. 1.1 If the billing cycle is `beginning of the month` and the payment schedule type is `prepay`, the first invoice - start date is the Entitlement's start date. - end date is the nearest first day of the month. - draft date is today. > Invoice period for past start date, monthly billing, prepay 1.2 If the billing cycle is `beginning of the month` and the payment schedule type is `postpay`, the first invoice - start date is the Entitlement's start date. - end date is the nearest first day of the month. - draft date is the nearest first day of the month. > Invoice period for past start date, monthly billing, postpay 1.3 If the billing cycle is `start of the entitlement` and the payment schedule type is `prepay`, the first invoice - start date is the Entitlement's start date. - end date is the Entitlement's start date in the next period. - draft date is today. > Invoice period for past start date, entitlement-start billing, prepay 1.4 If the billing cycle is `start of the entitlement` and the payment schedule type is `postpay`, the first invoice - start date is the Entitlement's start date. - end date is the Entitlement's start date in the next period. - draft date is the same as the end date. > Invoice period for past start date, entitlement-start billing, postpay #### 2. Start date in the future If the Entitlement's start date is in the future, the entitlement is considered pending. The invoicing process varies depending on the billing cycle and the payment schedule type. 2.1 If the billing cycle is `beginning of the month` and the payment schedule type is `prepay`, the first invoice - start date is the Entitlement's start date. - end date is the nearest first day of the month. - draft date is the same as the start date. > Invoice period for future start date, monthly billing, prepay 2.2 If the billing cycle is `beginning of the month` and the payment schedule type is `postpay`, the first invoice - start date is the Entitlement's start date. - end date is the nearest first day of the month. - draft date is the same as the end date. > Invoice period for future start date, monthly billing, postpay 2.3 If the billing cycle is `start of the entitlement` and the payment schedule type is `prepay`, the first invoice - start date is the Entitlement's start date. - end date is the Entitlement's start date in the next period. - draft date is the same as the start date. > Invoice period for future start date, entitlement-start billing, prepay 2.4 If the billing cycle is `start of the entitlement` and the payment schedule type is `postpay`, the first invoice - start date is the Entitlement's start date. - end date is the Entitlement's start date in the next period. - draft date is the same as the end date. > Invoice period for future start date, entitlement-start billing, postpay ### Usage Invoice Period The **Usage** invoicing period varies depending on the following factors: 1. Entitlement's start date: `past` or `future`. If the entitlement start date is in the past, the first invoice may include multiple periods. If the entitlement start date does not cover the full billing period, the invoice will be prorated accordingly. 2. Billing cycle: `beginning of the month` or `start of the entitlement`. The first invoice period is determined as follows: | **Entitlement Start Date** | **Billing Cycle** | **First Invoice Start Date** | **First Invoice End Date** | **First Invoice Draft Date** | | -------------------------- | ---------------------------- | ---------------------------- | ------------------------------------------- | ---------------------------- | | **Past** | **Beginning of the Month** | Entitlement's start date | Nearest first day of the month | Same as the end date | | **Past** | **Start of the Entitlement** | Entitlement's start date | Entitlement's start date in the next period | Same as the end date | | **Future** | **Beginning of the Month** | Entitlement's start date | Nearest first day of the month | Same as the end date | | **Future** | **Start of the Entitlement** | Entitlement's start date | Entitlement's start date in the next period | Same as the end date | You can consider the payment schedule type is always `postpay`, and the invoice period is calculated the same way as the Commit invoice above. ### Installment Invoice Period It is the specified installment payment date. ### Addon Invoice Period It is the specified addon charge date. ## Invoice Amount The invoice amount is calculated based on the entitlement terms and different invoice types. ### Commit Invoice Amount The **Commit** invoice amount is calculated based on the **Commitment** terms in the entitlement. #### Over a period When the entitlement start date is in the past, the first invoice may span multiple billing periods. For example, if an entitlement's start date is set to 3 months ago but is just being created now, the first invoice will cover all 3 months. #### Less than a period For partial billing periods, invoice amounts are prorated based on the actual days of service. ### Usage Invoice Amount **Usage Charge Fee** will be calculate based on the **Usage record reports** (Hourly reports shown in the red box) to create a **Usage** invoice: > Usage record reports highlighted in the metering flow Referring to [Calculate usage invoice fee](/metering/#calculate-usage-invoice-fee) for an overview of usage invoice fee calculation. #### Minimum Spend Minimum spend will be applied when calculating the dimension amount. The following options in the entitlement will be considered: 1. Minimum Commit Scope: - `DIMENSION`: Minimum commit applies to the entire dimension, including all group bys. - `DIMENSION_GROUP_BY`: Minimum commit applies to each dimension group bys. 2. Minimum Commit Prorated: If set to true, the minimum commit amount will be prorated based on the start and end dates of the entitlement period. ### Installment Invoice Amount The amount of an Installment invoice is defined by the installment payment terms in the entitlement. ### Addon Invoice Amount The amount of an Addon invoice is set by the applied addon amount. ## Trial If the entitlement includes a trial period, the invoice amount will exclude the usage during the trial period. Trial period works for the Commit invoice and Usage invoice. ### Commit Invoice Trial Period Commit invoice amount = Amount per day \* (Billed days - Trial days) For example, if an entitlement has the following details: - 30 days in a full period. - $300 for a full-period commit. - 20 days in the billing cycle. - 5 trial days. The invoice will be calculated as follows: 1. Amount per day = Full-period amount / Full-period days = $300 / 30 = $10 2. Billed days = Billed days - trial days = 20 - 5 = 15 3. Invoice amount = Amount per day \* Billed days = $10 \* 15 = $150 ### Usage Invoice Trial Period The usage record reports that are before the trial period will be excluded from the invoice amount calculation. For example, if an entitlement has the following details: - 100 units in total. - 20 units in the trial period. - $1 per unit. The invoice will be calculated as follows: 1. Billed units = Total units - Trial units = 100 - 20 = 80 2. Invoice amount = Billed units \* Unit price = 80 \* $1 = $80 ## Discount ### Usage Dimension Discount If the usage dimension includes a discount, the usage charge fee will exclude the discounted amount. ### Overall Discount The overall discount will be applied to the final total amount of the invoice, after all other discounts are calculated. It can be set as a fixed amount or a percentage of the total amount when [editing](#edit-a-draft-invoice) the invoice. --- Source: https://doc.fours.com/billing/payment/ # Payment Payment and Refund. --- ## Payment Payments are processed through the billing integration, which currently supports only Stripe. All payments are executed automatically, requiring no action from the buyer. ### Payment trigger After an invoice is issued and becomes `FINALIZED` status, the payment engine will automatically launch payment pipeline for the invoice. ### Payment transactions A payment for an invoice may involve multiple transactions, as several credits from the buyer's wallet can be applied alongside payments made through a provider like Stripe. ### Payment status Payment has the following 4 statuses. - **Pending**: The payment has not started yet. - **Processing**: The payment is in process. - **Success**: The payment was successful. - **Failed**: The payment has failed. Invoice's payment status is stored in `invoice.payment_status`, and each payment transaction has its own status. Payment status flow: Pending, then the payment pipeline starts; an invoice paid fully by credit goes straight to Success, a payment-provider payment goes to Processing and then to Success or Failed, and a failed payment can be retried manually - The `invoice.payment_status` will always align with the status of the latest payment transaction. - For credit payments, the status of the payment transaction will always be `success`. - If the total invoice amount is covered using credits, the `invoice.payment_status` will be marked as `success`. However, when other payment methods, such as Stripe, are used, the `invoice.payment_status` will depend on the success or failure of the payment transaction with the provider. - When using payment providers like Stripe, transaction failures may occur, resulting in multiple transaction records. The `invoice.payment_status` will be updated to reflect the status of the latest transaction, ensuring an accurate and current representation of the invoice’s payment status. ### Payment pipeline - Get buyer's wallets. - If credits are available, deduct credits first. - If the entire invoice amount is paid using credits, payment pipeline end with success. - If the invoice amount is partially paid using credits, update `invoice.payment_status` to `Processing`. - If there is a remaining amount that needs to be paid by the payment provider, call the Stripe payment API. - Select the detault payment method from the buyer’s wallets. - Call Stripe payment API to process the payment. ### Payment retry If the invoice payment fails, the seller can manually retry the payment through the Fours console. - A portion of the invoice amount may have already been paid using credits, which will be deducted first during the retry process. - During the retry, credits will continue to be prioritized for payment, with the remaining balance paid through the payment provider. ### Payment dispute If a dispute occurs, Stripe will handle this process. Fours will receive relevant webhook notifications from Stripe and then display the dispute in the corresponding payment transaction record on the Fours console. More about it: [Stripe doc](https://docs.stripe.com/disputes/how-disputes-work) ### Abnormal payment alert To avoid some extreme cases, Fours will regularly check the payments and compare them with the transaction status on Stripe to correct any potential issues. ## Refund Fours supports refund for a successful payment, and you need to initiate the refund manually in the Fours console. - All payments, including credit and other methods, can be refunded. - A single payment can be refunded multiple times, with each refund being a partial amount. - Refunds will be returned to the payment method used at the time of payment. - The refund process is done at the transaction level, not the invoice level. ### Credit refund - The refund of credits will be returned to the credit wallet used at the time of payment. - Refunds are only accepted when the credit wallet is in active status. - Credit refunds will always succeed. ### Stripe payment refund - The payment method for accepting refunds must be valid. If it has already expired or has been removed from the buyer's wallet, the refund cannot be processed. - A refund will create a new payment transaction record for easy reference of refund history and its status. - Refunds will be made using the Stripe SDK, and if this step fails, the refund will be marked as a failed. #### ACH Debit Refund If you request a refund for a payment that hasn’t completed yet (within a few hours of creating the Payment Intent), Stripe doesn’t submit the charge to the bank, essentially cancelling the original payment rather than refunding it. Stripe doesn’t explicitly label ACH Direct Debit refunds as refunds when we deposit the funds back to a customer’s bank account. Instead, we process refunds as a credit and include a reference to the statement descriptor for the original payment. More about it: [Stripe doc](https://docs.stripe.com/payments/ach-debit#ach-refunds) ### Abnormal refund alert Similar to payment, Fours regularly checks the refunds to make sure they are in the correct status. --- Source: https://doc.fours.com/billing/revenue/ # Revenue Revenue records and reports. --- ## Overview Fours Console provides a comprehensive view of revenue records and reports. Revenue records and reports are generated on successful payments of invoices. These records help track invoice amounts, collectable amounts, disbursements, and refunds. The Revenue dashboard turns marketplace billing streams into organized tables and charts, so finance, RevOps, and customer success teams can reconcile payouts, analyze revenue mix, and audit individual accounts. ## Revenue Reports Revenue reports provide visual insights through graphical charts, available in different sections of the Fours Console. ### Where to Find Revenue Reports - Company Page, **Revenue** Tab – Displays revenue data for an individual buyer: > Revenue chart on the buyer detail page - Entitlement Detail Page – Shows revenue data for a specific entitlement: > Revenue chart on the entitlement detail page ### Types of Revenue Reports Revenue reports are aggregated by date and categorized into three key metrics. | **Category** | **Description** | **Formula** | **Key Date** | | ------------------ | -------------------------------------------------------- | ----------------------------------------- | ------------------------- | | **Invoiced** 🧾 | Total amount billed on the invoice. | — | Invoice issue date | | **Collectable** 💸 | Amount that can be collected after fees and **credits**. | `(Total Payment - Partner Fee) + Credits` | Invoice Payment due date | | **Disbursed** 💰 | Amount sent to the seller after deducting partner fees. | `Total Payment - Partner Fee` | Payment Disbursement date | #### FAQ ### In Fours, I can see two different amounts: Invoiced and Collectable. What is the difference between them? The invoiced value is the amount your customer was invoiced. The collectable amount is the amount AWS will pay once the fees are deducted. ### Understanding Important Dates - Invoice Date: The date when the invoice was issued. - Payment Due Date: The deadline for the buyer to complete the payment. - Disbursement Date: When the payment is successfully processed and transferred to the seller. ## Revenue Records Revenue records are detailed financial records associated with invoices and payment transactions. There are two types of revenue records: **joined records** and **raw records**. ### Joined Records A joined record is directly linked to an invoice, sharing the same ID. It is created by consolidating all payment transactions associated with the invoice into a single comprehensive record. This aggregated, customer-centric view is ideal for understanding an account's overall financial health and tracking exactly what each buyer owes. > Joined records table in the Revenue dashboard The columns available in this view include: - **Contract & CRM identifiers:** `Product`, `Entitlement`, `CRM Opportunity ID`, `Offer External ID`, `Buyer`, `Country`, `Category`, `Channel` - **Timeline metrics:** `Entitlement Start Date`, `Entitlement End Date`, `Invoice Date`, `Due Date`, `Disburse Date` - **Financial calculations:** `Invoice Amount`, `Partner Fee`, `Partner Fee (%)`, `Collectable Amount`, `Disburse Amount`, `Tax Amount` - **Reconciliation fields:** `Payment ID`, `Earning ID`, `Invoice ID`, `Bank Trace ID`, `Disbursement Reference Number` - **Refund adjustments:** `Refund Invoice Date`, `Refund Invoice Amount`, `Refund Disburse Date`, `Refund Disburse Amount` - **Channel partner context:** `Reseller Name`, `Reseller ID` ![Revenue dashboard Joined Records tab](images/revenue-reporting-in-suger-1.png) ### Raw Records A raw record represents one payment transaction associated with an invoice, surfaced exactly as it is emitted from the cloud provider's native billing system. Use this view to audit individual line items or run deep reconciliation checks against your actual marketplace payouts. For details, see [payment transactions](/billing/payment#payment-transactions). > Raw records table in the Revenue dashboard The columns available in this view include: - **Transaction identifiers:** `Date`, `Partner`, `Product`, `Entitlement`, `Buyer`, `Disbursement Reference Number` - **Status & type controls:** `Type`, `Status`, `Amount` ![Revenue dashboard Raw Records tab](images/revenue-reporting-in-suger-2.png) ## Check if an Invoice Has Been Paid You can confirm whether an entitlement has been invoiced and paid from either the entitlement detail page or the Revenue tab. 1. Open the **Entitlement** section and search for the active entitlement you want to check. 2. Click the entitlement and scroll down to the **Revenue Record** tab. 3. Review the revenue record details, presented in three columns: - Invoice amount - Collectable amount - Disbursement amount 4. Check the line items — invoice paid, partner fee, partner fee (%), collectable amount, due date, and actual disbursement date. 5. Estimate the payment terms for each cloud marketplace by comparing the **Due Date** with the **Disbursement Date**. For a broader view across all entitlements, open the **Revenue** tab, where invoice date, invoice amount, partner fee, partner fee (%), collectable amount, due date, disbursement date, and disbursement amount are shown together with charts and can be downloaded as a CSV. ## Common Workflows ### Finance: Disbursement Tracking & Month-End Close Track down outstanding marketplace payouts: 1. Click the **Disbursement Date** column header to sort your records chronologically. 2. Filter for rows where the disbursement date is empty or set to a future date to isolate pending cash flow. 3. Compare the **Due Date** against the **Actual Disbursement Date** to map cash-flow timing and spot cases where buyer payment terms or marketplace processing windows are delaying payouts. ### RevOps & Alliances: Analyzing Revenue Mix & Custom Views - **Usage vs. Commit breakdown:** Every row shows whether the funds came from a flat contract milestone (**Commit**) or metered consumption reporting (**Usage**), which helps you analyze product revenue velocity and explain invoice changes to buyers. - **Cloud-specific reconciliations:** Filter the view by a single cloud provider (**AWS**, **Azure**, or **GCP**) to reconcile against that marketplace's payout schedule. - **Column customization:** Click the **Columns** icon to build a tailored layout. Channel teams can add parameters like _Reseller Name_ and _Reseller ID_ to track multi-party deals, while operations teams can reorganize columns to match internal data models. ### Customer Success: Account-Level Financial Auditing 1. Apply the **Buyer & Entitlement Filter** to search for a single customer account (e.g., _Acme Corp_). 2. Review the entire invoicing history tied to that account to confirm gross amounts, applied refunds, and historical collections. 3. Click any row item to jump directly from the Revenue dashboard into the underlying **Entitlements** detail page to check contract dates, installment metrics, and usage configurations. ## Export Revenue Data If you are on the finance or sales-ops team, you can export revenue data for analysis in a spreadsheet or ERP platform. 1. Open the **Revenue** tab, where transaction data is presented as line and bar graphs. Each transaction includes details like entitlement, invoice, partner fee, collectable amount, due date, and disbursement date. 2. Use the transaction data to identify paid and outstanding invoices and understand payment terms. 3. Adjust the filter criteria: - Change the time frame by selecting days, weeks, or months from the top right-hand corner. - Change the cloud provider and apply additional filters with the **Filter** button. - Add or remove columns to tailor the view. 4. Click **Download CSV** to export the data. The export captures all hidden and visible columns currently active in your table layout, so configure column visibility (for example, including `Invoice ID`, `Tax Amount`, and net collectible data) to match your ERP data model before downloading. ## Syncing Financials with Your CRM To keep bookings, billings, and cash collections aligned, every transaction record points back to its corresponding contract entitlement and CRM object. - **ARR tracking accuracy:** Cross-reference linked Salesforce or HubSpot opportunity IDs directly within the table so your internal dashboards match reality. - **Custom external processing:** Filter by a date window (such as _Last 7 days_, _Last 30 days_, or a custom range) and click **Download CSV** to generate a file ready for ingestion into your ERP platform, financial spreadsheets, or metrics dashboards. ## Troubleshooting | Issue | Cause | Resolution | | --- | --- | --- | | Why don't I see any revenue listed yet? | The invoice has not been issued, or metrics haven't registered. | Verify that usage has been reported for the period, or check whether the underlying private offer contract has a future start date. | | Why hasn't the money been disbursed yet? | Standard collection or marketplace payout processing windows are still open. | Check the Due Date column. Payouts remain pending until the buyer's payment terms elapse and the cloud provider's trailing disbursement cycle closes. | | Why is the amount lower than expected? | Deductions or adjustments were processed at the marketplace layer. | Open the column customizer and toggle on Partner Fee (%) and Tax Amount to review the commissions or local taxes withheld at the source. | :::info If official marketplace payout timelines have lapsed with no disbursement, ingested amounts don't match your contract terms, or refunds don't reflect correctly, contact [support@suger.io](mailto:support@suger.io). ::: ## Frequently Asked Questions - **What is the difference between Joined Records and Raw Records?** **Joined Records** roll your financial fields up into a clean, aggregated, customer-centric view, making it easy to see overall buyer account balances. **Raw Records** display every transaction exactly as passed by the cloud provider's billing service without aggregation, which is required for month-end ledger reconciliation. - **What is the difference between an Invoice and a Disbursement?** An **Invoice** is a billing event — it confirms that the cloud provider has charged the customer and recorded the transaction. A **Disbursement** is actual cash flow — it marks the point where the cloud provider rolls those collected funds into a payout and deposits them into your bank account. - **How does Fours distinguish between a Commit and a Usage charge?** Fours reads the underlying line-item metadata provided by the cloud billing engine. Contracts with upfront or scheduled flat-fee milestones are categorized under **Commit**, while consumption metrics pushed from your telemetry appear as **Usage** entries. - **Can I use the CSV export to feed my ERP platform?** Yes. The **Download CSV** function captures all hidden and visible columns currently active in your table layout. By configuring your column visibility to match your ERP data model, you can generate an import-ready ledger file. - **How do refunds show up on this page?** If a customer refund is issued, the dashboard tracks it through dedicated adjustment fields: `Refund Invoice Date`, `Refund Invoice Amount`, `Refund Disburse Date`, and `Refund Disburse Amount`, giving you complete visibility over net-revenue corrections. --- Source: https://doc.fours.com/billing/amend-cancel-entitlement/ # Amend or Cancel an Entitlement Change or cancel an active customer contract across AWS, Azure, and GCP marketplaces. --- ## Overview Cloud marketplaces don't allow direct edits to active entitlements. Instead, each hyperscaler enforces a controlled contract lifecycle mechanism for renewals, upsells, and mid-term adjustments. While the outcome is similar (modified commercial terms), the execution differs across AWS, Azure, and GCP. | Marketplace | Amendment mechanism | Key limitation | | --- | --- | --- | | AWS | Agreement-Based Offer (ABO) | Only supported for SaaS Contract / Contract + Consumption models | | Azure | Net-new private offer | Ongoing offers can't be edited; you must cancel/recreate or issue a new renewal offer | | GCP | Replacement Offer | You can't change the underlying product, plan, or pricing model | In each marketplace, an active customer contract maps to an **Entitlement** in Fours, even though the marketplaces name it differently (AWS calls it an Agreement, Azure a Subscription, GCP an Entitlement). ## Amend an AWS agreement In AWS, an active customer contract is called an **Agreement**. In Fours, this is shown as an **Entitlement**. If you want to change an existing customer deal (for example, increase usage, upgrade pricing, or extend the contract), you don't create a new agreement. Instead, you create an **Agreement-Based Offer (ABO)**. ABOs let you safely modify an active contract while keeping everything tied to the original entitlement. 1. Go to the **Entitlements** tab in Fours. 2. Find and open the active entitlement (your customer's agreement). 3. Click **More action**, then select **Upsell / Renew**. 4. Fill in the updated terms (pricing, quantity, or contract length). 5. Create the offer. Once the buyer accepts, the original contract is updated rather than replaced. For more details, see [Amending agreements in AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/private-offers-upgrades-and-renewals.html). ### Cancel an AWS agreement To cancel an agreement, see [Refunds and Cancellations](/aws-marketplace/refunds-cancellations/). ### Issue an AWS refund To issue a refund, see [Refunds and Cancellations](/aws-marketplace/refunds-cancellations/). ## Amend an Azure subscription In Azure, an active customer contract is called a **Subscription**. In Fours, this is shown as an **Entitlement**. Azure doesn't allow editing an existing private offer or subscription once it's active. Instead, every change is handled by creating a new private offer that replaces or extends the existing commercial terms. 1. Go to the **Offers** tab in Fours. 2. Click **+ New Private Offer**. 3. Select the Azure product tied to the customer. 4. Enter the customer's **Azure Billing Account ID**. 5. Check **Customer Renewals**. This tells Azure the offer is linked to an existing subscription. 6. Update pricing, quantity/usage, and the start and end dates. 7. Click **Create Offer** and send it to the buyer. ### Cancel an Azure subscription Azure subscriptions can only be cancelled directly in Microsoft Partner Center. See [Cancel an Azure Marketplace subscription](https://learn.microsoft.com/en-us/partner-center/developer/cancel-an-azure-marketplace-subscription#partner-center-method). ## Amend a GCP entitlement In GCP, a customer's active contract is called an **Entitlement**, which matches Fours' terminology. If you want to renew or upsell an active customer deal, you use a **Replacement Offer**. :::warning - Each installment value must be **≥ 50% of the previous installment's value**. - The amended contract's **total contract value must be ≥ 50% of the current contract's total contract value**. ::: 1. Go to the **Offers** tab in Fours. 2. Click **+ New Private Offer**. 3. Select the **GCP product** tied to the customer. This pulls the existing offer details so you can reuse the current structure. 4. Update the **Start and Expiry Date** of the contract. 5. Update the number of remaining installments. Installments that have already been paid can't be changed. 6. Attach a **EULA** to the offer. 7. Review your details and click **Create** to generate and send the private offer to the buyer. ### Cancel a GCP entitlement GCP entitlements can only be cancelled directly in Google Cloud Partner Center. See [Cancel an active order](https://docs.cloud.google.com/marketplace/docs/partners/offers/cancel-active-order). ## Amend reseller deals (CPPO / MPO / RPOP) | Marketplace | How to amend a reseller deal | | --- | --- | | AWS | Issue a new resale authorization with the updated terms. The reseller then uses that authorization to create an ABO for the buyer. See [CPPO](/aws-marketplace/cppo/). | | Azure | In-place amendment of an active Azure reseller (Multiparty Private Offer / MPO) deal isn't available in Fours today. To adjust the terms, contact [support@suger.io](mailto:support@suger.io) and the team will advise on the correct Azure Marketplace procedure. | | GCP | Reseller private offers can be directly amended using a replacement offer. See [Create Private Offer](/gcp-marketplace/create-private-offer/) and [Configure a reseller private offer plan](https://docs.cloud.google.com/marketplace/docs/partners/resell/reseller-private-offer-plans). | --- Source: https://doc.fours.com/billing/aws-refunds-cancellations/ # AWS Refunds and Cancellations Handle AWS Marketplace refund and cancellation requests directly from the Fours Console. --- ## Overview As a seller, you can cancel active AWS Marketplace entitlements and issue refunds without leaving the Fours Console. Requests are tracked on the entitlement record, so you can follow their status end to end. For AWS Marketplace refund and cancellation policies, see [Refunds and cancellations in AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/refunds.html#refund-approval). :::info **Permission required.** You need **Admin** access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). ::: :::warning Always submit the refund request **before** canceling. Once an entitlement is canceled, you can no longer issue a refund for it through the Fours Console. ::: ## Cancel an active entitlement As a seller, you may need to initiate a cancellation for: - **Contractual errors:** Correcting a private offer that was accepted with the wrong terms or pricing. - **Agreement replacements:** Facilitating a mid-term downgrade or a change in invoicing terms. - **Buyer requests:** Processing cancellations for private offers or public contracts after the 48-hour self-service window. - **Accidental subscriptions:** Resolving cases where a buyer auto-renewed unintentionally or chose the wrong offer. - **Product sunset:** Ending support for a product that is being removed from AWS Marketplace. ### Seller-initiated cancellation 1. Go to the **Entitlement** page in the [Fours Console](https://console.suger.io/entitlement). 2. Open the specific entitlement you want to cancel. 3. Click **More actions** in the upper-right corner, then select **Request cancellation**. ![Requesting AWS entitlement cancellation in the Fours Console](images/handle-aws-marketplace-refunds-and-cance-1.png) 4. Select the **Reason** for cancellation, then add an optional **Description** to provide context for the buyer. ![Create a cancellation request](images/handle-aws-marketplace-refunds-and-cance-2.png) 5. Click **Review**, then double-check the cancellation request details. 6. Click **Confirm & Submit**. ![Confirm cancellation](images/handle-aws-marketplace-refunds-and-cance-3.png) The buyer is notified and can approve or deny the request. If they don't respond within 7 days, AWS automatically approves it. ### Buyer-initiated cancellation Buyers can cancel their subscriptions directly from the AWS Marketplace console, and no action is required from you to initiate it. When they do: 1. You receive a `PENDING_CANCEL` event. 2. If you use metered billing, report your final usage as soon as possible. 3. After the entitlement is canceled, no further billing adjustments can be made. ## Issue a refund Refunds are always initiated by the seller. If a buyer requests one directly from AWS, AWS Customer Service redirects them to you. After you and the buyer agree on the refund, you can use it to correct billing issues such as overcharges, usage errors, or charges the buyer should not have received. :::warning Refunds don't end the entitlement, so the buyer retains access unless you also submit a cancellation afterward. ::: 1. Go to the **Entitlement** page in the [Fours Console](https://console.suger.io/entitlement). 2. Open the specific entitlement you want to refund. 3. Click **More actions** in the upper-right corner, then select **Request Refund**. ![Requesting a refund for AWS in the Fours Console](images/handle-aws-marketplace-refunds-and-cance-4.png) 4. Review and check the affected invoice(s), then select **Next**. ![Selecting invoices](images/handle-aws-marketplace-refunds-and-cance-5.png) 5. Select the **Reason Code**, then enter the **Refund Amount**. ![Refund details](images/handle-aws-marketplace-refunds-and-cance-6.png) 6. Select **Next**, then review the refund details. 7. Select **Submit** when done. ![Confirm refund](images/handle-aws-marketplace-refunds-and-cance-7.png) Billing adjustments are processed automatically once submitted and validated by AWS. The update typically appears on the customer's AWS billing account within **24–48 hours**. ### What happens after a refund? You don't need to take any action after submitting, but here's what to expect: - **If you've already been paid:** AWS deducts the refunded amount from your next payout cycle. - **If the invoice is unpaid:** the charges are adjusted before payment is collected. AWS Marketplace fees are also recalculated based on the adjusted amount, not the original invoice total. ## Track your requests ### Cancellation requests 1. Go to the **Entitlement** page in the [Fours Console](https://console.suger.io/entitlement). 2. Open the entitlement you want to check. 3. Click **More actions** in the upper-right corner, then select **View Cancellation Requests**. ![View cancellation requests](images/handle-aws-marketplace-refunds-and-cance-8.png) ### Refund requests Refund requests are processed by AWS after submission. While the billing adjustment may appear on the customer's AWS billing account within 24–48 hours, refund details can take 1–2 months to appear in Fours because they are only reflected after AWS processes the updated customer billing data. You can track processed refunds from the entitlement's **Revenue** tab: 1. Go to the **Entitlement** page in the [Fours Console](https://console.suger.io/entitlement). 2. Open the entitlement you want to check. 3. Go to the **Revenue** tab and scroll down to the **Refund History** section. 4. Review the dedicated refund columns: **Refund Invoice Date**, **Refund Invoice Amount**, **Refund Disburse Date**, and **Refund Disburse Amount**. ![Refund in the Revenue tab](images/handle-aws-marketplace-refunds-and-cance-9.png) ## Frequently asked questions **Do I need to do anything to enable self-service cancellation and refunds?** No setup is required. The feature is automatically available to all Fours customers. If you don't see the **More actions** button, make sure you're viewing a specific entitlement record (not the main dashboard) and that your user role isn't read-only. **Do I need to refund before canceling?** Yes. You must request the refund **before** cancellation. If you cancel first, you won't be able to issue a refund afterward. **Can I still use AWS support tickets for cancellations?** Yes. However, the self-service workflow in Fours is typically faster and provides built-in request tracking from the entitlement record. **Does the SCABA process work for Channel Partner Private Offers (CPPOs)?** No, there is no SCABA process for CPPO agreements at this time. This AWS functionality is exclusively for direct transactions. **We need to refund an entitlement that was invoiced but not yet disbursed. Do we issue a $0 refund or wait?** You can still issue a refund as long as the invoice exists. AWS adjusts the invoice and prevents the payout from being disbursed. --- Source: https://doc.fours.com/billing/usage-credit/ # Usage Credit Add a USD-denominated allowance to an entitlement's usage-based metering. --- ## Overview Usage credit lets you add a USD-denominated allowance to an entitlement's usage-based metering — useful for goodwill credit, promotional allowances, or SLA make-goods. It only takes effect if the entitlement has a usage-based metric defined. Before you add credit, check two things: - **No usage-based metering, no effect.** If the entitlement is a flat commit with no usage component, adding credit does nothing. - **Don't stack with your metering service's own credits.** If your metering service (Orb, Metronome, etc.) already issues credits, adding Fours Credit on top can double-credit the buyer. :::warning Credit amounts can't be decreased or reverted — via Console or API — once added. If you add the wrong amount, contact Fours support to correct it. ::: ## How billing priority works When a usage record comes in, Fours offsets it in this order: | Order | Offset type | Notes | | --- | --- | --- | | 1 | Fours Credit | Consumed first | | 2 | Commit | AWS/GCP commit amount, or Azure Flat Rate | | 3 | Included Quantity | Not applicable for AWS; Azure Included/Infinite Included; GCP tiered free quantity | ## Add credit in the Fours Console 1. Go to the specific **Entitlement** record. 2. Scroll down past the top summary fields (**Auto Renew**, **Product**, **Start/End Date**, **Term Length**) to the **Entitlement term** section. - This is easy to miss — the action lives below the fold, not in the top summary. 3. Next to **Entitlement term**, click **Add Credit**. 4. In the **Add Credit to Entitlement** panel, optionally select an **Entitlement Term** from the dropdown. - If left blank, credit applies to the default entitlement term. 5. Enter the **Credit Amount** in USD. 6. Submit. Once submitted, the credit shows up in two places: - **Credit** and **Used Credit** fields in the entitlement's Detail panel. - Per-term breakdown in the Entitlement term table. ![Add Credit to Entitlement panel](images/add-usage-credit-to-an-entitlement-1.jpeg) ## Add credit via API Use the `addEntitlementCredit` REST API. Request payload: - `organizationID` - `entitlementID` - `entitlementTermID` (optional) - `creditAmountIncrement` The response confirms the new total credit amount on the entitlement. Credit amounts must be positive — the API has no decrease or revert path either. ## Credit added by the Chargebee usage sync If Fours reports your Chargebee usage to the marketplaces, the sync can add credit to an entitlement term on its own. Marketplaces don't accept negative usage, so an amount Fours has already reported can't be pulled back — the sync credits it instead, in two cases: - **A discount lowers the invoice.** When a Chargebee billing window closes and the metered line on its invoice, net of Chargebee discounts, comes to less than Fours already reported for that window, Fours adds the difference as credit. - **The invoice is voided.** When a Chargebee invoice is voided after Fours reported its window, Fours credits the reported amount back to the entitlement that was billed. This is the same credit you add by hand: it shows in the **Credit** and **Used Credit** fields, it is consumed before commit and included quantity, and it can't be decreased. Don't also add manual credit for the same Chargebee discount or voided invoice, or the buyer is credited twice. For how each billing window is settled, see [How Fours settles each billing window](/integrations/chargebee/#how-fours-settles-each-billing-window). ## Troubleshooting | Issue | Possible cause | Resolution | | --- | --- | --- | | Added credit isn't reducing the buyer's bill | Entitlement has no usage-based metric | Usage credit only applies to usage-based metering — verify the entitlement type before adding credit | | Buyer appears to be credited twice | Metering service (Orb, Metronome, etc.) also has its own credit for this usage | Use only one credit source at a time — don't stack Fours Credit with a metering-service credit | | Added the wrong credit amount | Credit amounts can't be decreased or reverted after submission | Contact Fours support to correct the entitlement | | Credit appears on an entitlement term that nobody added | The Chargebee usage sync added it for a Chargebee discount or a voided invoice | Expected — see [Credit added by the Chargebee usage sync](#credit-added-by-the-chargebee-usage-sync). Don't add manual credit for the same amount | ## Frequently asked questions **Does credit work if my entitlement has no usage-based metric?** No — it has no effect at all. **What gets consumed first, my credit or the buyer's included quantity?** Credit first, then commit, then included quantity. **Can I reduce a credit amount I added by mistake?** No. Contact Fours support — there's no self-service way to decrease or revert credit. **Will this double-credit my buyer if my metering service already gives credits?** Possibly. Don't run both at the same time. --- Source: https://doc.fours.com/billing/erp-reconciliation/ # ERP Reconciliation Connect your marketplace transactions to your ERP so Finance can trace every deal from contract to cash deposit. --- ## Overview When you sell through cloud marketplaces, you don't receive a separate payment for every customer. Instead, the marketplace typically sends a single payment that combines revenue from many different customers and transactions. For Finance teams, this creates a challenge: > _How do you know which customers, contracts, and invoices make up that payment?_ Fours answers that question by connecting your marketplace transactions to your ERP system (such as NetSuite or QuickBooks). It tracks the lifecycle of each deal, matches marketplace payments back to the original contracts, and syncs the resulting financial data to your accounting systems. :::info Fours currently supports native ERP integrations with Oracle NetSuite and QuickBooks. ::: ## How Fours tracks your marketplace revenue To reconcile your books accurately, Fours tracks every deal through three financial stages: | Stage | What it means | What your finance team does with it | | --- | --- | --- | | **Invoiced amount** | The total amount the marketplace billed to your buyer. Confirms the billing cycle has started. | Verify the deal was activated and billing began on the right date. | | **Collectable amount** | Your expected net revenue after the marketplace deducts its transaction fee. | Forecast cash flow and confirm the correct fee rate was applied. | | **Disbursed amount** | The final amount deposited to your bank account. | Reconcile against your bank statement and close out the invoice. | Tracking all three stages gives your finance team a clear, auditable trail from the original deal to the final cash deposit. ## What Fours automates for you Once you connect your ERP to Fours, the following happens automatically: - **When a buyer accepts a private offer**, Fours creates or matches a customer record in your ERP and links it to the contract terms from that deal. - **As billing cycles run**, Fours maps each invoice to the original sales opportunity in your CRM, so there's a clean trace from the deal to the expected billing schedule. - **When the marketplace sends a disbursement**, Fours ingests that payment data, splits it into individual invoice-level records, and matches each one to the right customer. - **Every day**, Fours pushes those updated records to your ERP, automatically marking invoices as paid or unpaid based on what the marketplace has confirmed. ## Connect your ERP To start reconciling, connect your accounting system to Fours: - [Integrate Oracle NetSuite with Fours](/integrations/netsuite/) - Integrate QuickBooks with Fours --- Source: https://doc.fours.com/billing/ # Billing Billing is how you charge the customers you sell to: define the units you meter, price them, put that price on an offer, report the usage, and issue the invoice. How much of the lifecycle you run yourself depends on the channel. When you bill through your own Stripe account, Fours issues the invoice and collects the payment. When you sell through AWS, Azure, GCP, or Oracle Cloud, the marketplace bills the buyer and pays you your share — Fours supplies the metered usage those invoices are built from, then tracks what comes back. Start with the [Overview](/billing/overview/) if you are new to it: it walks the whole path once and explains when you actually get paid on a marketplace deal. Every page in this section is linked below. ## Go from a price to a paid invoice 1. **Define what you charge for** — [Billable Metrics](/billing/billable-metrics/) name the unit you measure and how it is aggregated, and must exist before any usage-based offer. A [Price Model](/billing/price-model/) turns that into money: a flat fee as installments or recurring commits, usage metering, or both, on a billing cycle and interval you choose. 2. **Set up the customer and the deal** — create a [Buyer](/billing/buyer/) for the customer you bill directly, send an [Offer](/billing/offer/) carrying the product, contract dates, and price model, and the accepted offer becomes an [Entitlement](/billing/entitlement/) — the active contract that drives billing and tells you when it ends. 3. **Report the usage** — send usage records through [Metering](/metering/), from your own backend, a connected billing engine, or a CSV upload. Fours aggregates hourly and daily, then totals each billable dimension when the period closes. 4. **Invoice and collect** — Fours generates an [Invoice](/billing/invoice/) from the entitlement and its aggregated usage, which you can edit while it is still a draft. Once finalized, the [Payment](/billing/payment/) pipeline charges it automatically and records every transaction and its status. 5. **Track and reconcile** — [Revenue](/billing/revenue/) reports invoiced, collectable, disbursed, and refunded amounts, with charts on the buyer and entitlement pages. [ERP Reconciliation](/billing/erp-reconciliation/) breaks a lump-sum marketplace payout back into the individual contracts and invoices behind it, and syncs the result to your accounting system. ## Change a deal after it goes live - **[Amend or Cancel an Entitlement](/billing/amend-cancel-entitlement/)** — marketplaces do not allow direct edits to an active contract, so each cloud has its own mechanism: an AWS agreement-based offer, an Azure net-new private offer, a GCP replacement offer. This page covers what each one can and cannot change. - **[AWS Refunds and Cancellations](/billing/aws-refunds-cancellations/)** — request a refund and cancel an active AWS entitlement from the console, and track the request on the entitlement record. Order matters: once you cancel, you can no longer refund from the console. - **[Usage Credit](/billing/usage-credit/)** — add a USD allowance that is consumed ahead of commits and included quantity. It only has an effect on entitlements with a usage-based metric, and the amount cannot be reduced once added. ## Scope and limits :::info **Direct billing runs on Stripe.** Buyers, payments, and Fours-issued invoices go through the Stripe billing integration — the only payment integration supported today. A buyer's partner cannot be changed after the buyer is created, so a customer you bill on two partners needs two buyer records. **Metering spans the marketplaces.** Usage reporting is normalized across AWS, Azure, GCP, and Oracle Cloud. Snowflake and Alibaba usage is reported through their own marketplace sections. **ERP reconciliation** has native integrations with Oracle NetSuite and QuickBooks. **Two things this section is not.** What *you* pay Fours for AI usage is [Insulin Billing](/insulin/billing/). Cross-channel revenue reporting, aging, and payout tracking live in the [Revenue](/revenue/) workspace. ::: --- Source: https://doc.fours.com/aws-marketplace/self-serve-onboarding/ # Self Serve Onboarding Guide Everything you need to get live on AWS Marketplace with Fours, step by step. --- :::info New to cloud marketplaces? See [What Is a Cloud Marketplace](/concepts/what-is-cloud-marketplace/) for the basics before diving in. ::: ## What to expect Fours connects your AWS Marketplace seller account to a single console where you manage listings, private offers, and revenue, so you don't have to work directly inside AWS Marketplace's own interface for day-to-day tasks. This is a self-serve guide — no need to wait for a meeting to get started. Most of the hands-on work takes only a few hours; the longest part is waiting for AWS to review your listing (about 2 weeks). Seller verification itself is quick — usually under 48 hours. Use your dedicated Slack channel for questions at any point. | Phase | What you're doing | Est. time | | --- | --- | --- | | 0 — Become an AWS seller | Seller registration, tax, bank account, verification | Less than 1 hour work, then ~48 hours AWS review | | 1 — Get Fours Console access | Create & get approved on the Fours console | Day 1-2 | | 2 — Connect & submit your listing | Connect AWS Marketplace, build and submit your listing | ~1-2 hrs work, then ~2 weeks AWS review | | 3 — Go live & test | Confirm listing, send test private offer | Less than 1 hour | | 4 — CRM integration (optional) | Connect Salesforce or HubSpot | Anytime after Phase 1 | | 5 — Co-Sell setup (optional) | Connect AWS ACE co-sell | Anytime after Phase 1 | Work through Phases 0-5 in order — Phases 4 and 5 are optional, skip them if they don't apply to you. :::tip If you're working toward a specific go-live date: start seller verification and listing setup as early as possible, submit your listing to AWS as soon as it's ready, and respond quickly to any AWS review feedback so you can resubmit without unnecessary delays. Let your Fours team know in your Slack channel as early as possible if you need to launch sooner — we'll do everything we can on our side to keep your onboarding moving. ::: ## Before you start You don't need everything perfect on day one, but having these ready will help you move faster: - **Your business** — a registered legal business entity and a company email address (not a personal Gmail or similar). - **An AWS account** — an active AWS account with billing enabled. If you don't have one yet, create one at [aws.amazon.com](https://aws.amazon.com/). - **Someone with AWS admin access** — required to register as an AWS seller (Phase 0) and to create the IAM role that connects AWS to Fours (Phase 2, ~20 minutes). Without this access, steps will fail or look incomplete, not broken. - **Someone who can make pricing decisions** — needed when you create your listing (Phase 2), since AWS requires at least one price above $0.00, even if you plan to sell only through private offers. - **Your product** — a live, publicly accessible URL that AWS can reach, plus a support email and support URL (AWS checks these during listing review). - **A logo** — a company or product logo in PNG format. Bank account details for payouts and tax forms can be set up as you go through Phase 0. ## Phase 0: Become an AWS Marketplace seller Before you can publish products on AWS Marketplace or connect your account to Fours, you must complete AWS's one-time seller registration and verification process. Registration happens entirely in AWS — this section walks you through what to do and in what order, with links to the official AWS instructions for each step. It's how Independent Software Vendors (ISVs), Managed Service Providers (MSPs), and other eligible entities list, manage, and monetize software or services through AWS's global customer base. Completing your public profile lets you list free products; providing tax and banking information lets you publish paid and BYOL (Bring Your Own License) products. :::tip Registration goes through **AWS Partner Central**, which links directly to the [AWS Marketplace Management Portal (AMMP)](https://aws.amazon.com/marketplace/management/). You'll create your seller profile, verify your identity, and set up your business details. ::: **Estimated time:** Less than 1 hour of hands-on work, plus typically about 48 hours for AWS to review and verify. The full process takes 1–4 weeks end to end when Know Your Customer (KYC) verification isn't required; if it is, plan for KYC separately — AWS puts it at approximately 2–3 months (see Step 6). Before you register, have these ready: - **AWS account** — an existing AWS account, or a new one dedicated to marketplace activity (using a separate account from your production workloads is recommended — see Step 2). - **Eligible jurisdiction** — you must be a permanent resident of, or have a business entity in, an eligible country or region. See [Eligible Jurisdictions](https://docs.aws.amazon.com/marketplace/latest/userguide/user-guide-for-sellers.html#additional-seller-requirements-for-paid-products). - **Business information** — legal business name, address, official website, and contact details. - **Government-issued photo ID** — required to verify your identity during registration. - **Tax information** — relevant tax identification numbers and documentation (for example, a W-9 for U.S. entities or a W-8 for non-U.S. entities). - **Bank account details** — a bank account capable of receiving USD disbursements. - **AWS alliance lead** — the name and email of the person managing your AWS partner relationship. Confirm you meet AWS's eligibility requirements (Step 1 below), then work through registration in order — some steps won't become available until you've finished the previous one. Here's the sequence: | Step | What it covers | Can't start until | | --- | --- | --- | | 1: Check eligibility | Confirm AWS's baseline seller requirements | Nothing — do this first | | 2: Choose your selling account | Pick (or create) the AWS account that becomes your seller of record | Nothing | | 3: Register & public profile | Company name, website, description, logo, support contact info | Selling account chosen | | 4: Tax information | Tax interview (W-9 for US entities, W-8 for non-US) | Public profile created | | 5: Bank account & disbursement | Add a USD-capable bank account, then set your payout currency and schedule | Tax information complete | | 6: KYC — Know Your Customer (only if required) | Business and beneficial-owner verification | Typically after bank account setup | | 7: Bank account verification (only if required) | Upload a bank statement matching your account details | Typically after KYC, if required | :::info KYC and bank account verification (Steps 6 and 7) only apply to some sellers — AWS determines whether these additional steps are required during your registration. KYC typically applies to sellers operating in regions such as EMEA and the Republic of Korea; if it applies to you, complete it to avoid disbursement delays. ::: ### Step 1: Check your eligibility Confirm you meet AWS's baseline requirements. All sellers must: - Have an active AWS account in good standing - Sell publicly available, production-ready software - Have a defined customer support process If you plan to sell paid or BYOL products, your business must be incorporated in an AWS-approved country or region, and individual sellers must be permanent residents or citizens of one of those locations. For more details, see [Seller eligibility requirements](https://docs.aws.amazon.com/marketplace/latest/userguide/seller-eligibility.html). ### Step 2: Choose the AWS account you'll use for selling To register as a seller, you must first have an active AWS account. If you don't already have one, [register on the AWS website](https://console.aws.amazon.com/) and use your credentials to sign in to the AWS Management Console. AWS recommends using a **dedicated AWS account** for your marketplace seller activity. This account becomes your seller of record and is used for listings, reporting, payments, and communications from AWS Marketplace. A dedicated account makes it easier to separate marketplace operations from your other AWS workloads, so if you're creating one from scratch, consider using a subaccount rather than the account where your product is deployed. When setting up access, use IAM roles instead of sharing root credentials, and consider using a role-based email address that your marketplace team can monitor. For more details, see [AWS account setup considerations and best practices](https://docs.aws.amazon.com/marketplace/latest/userguide/account-considerations.html). :::tip **Which account should I choose if I have more than one?** You can choose any AWS account as long as it is a U.S. account or from another [eligible jurisdiction](https://docs.aws.amazon.com/marketplace/latest/userguide/user-guide-for-sellers.html#eligible-jurisdictions). ::: ### Step 3: Register as a seller and create your public profile Your public profile is visible to potential customers and includes essential information about your company. Have these ready before you start: - Government-issued photo ID - Official business name and website - Business tax ID (EIN for U.S. companies; VAT or GST number for non-U.S. companies) - Name and email of your AWS alliance lead **Instructions:** 1. Navigate to the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/) and click **Register now**, then sign in with your AWS account credentials. ![AWS Marketplace Management Portal registration screen](images/aws-aws-marketplace-seller-registration-guid-1.png) 2. Fill in your company details, accept the terms and conditions, and provide the necessary information. ![AWS Marketplace seller registration form](images/aws-account-setup-2.png) 3. Once you complete registration, you're taken to the [AWS Marketplace Management Portal settings](https://aws.amazon.com/marketplace/management/seller-settings/) to set up your public profile. Select **Add public profile** and provide: - **Seller Display Name**: Your company's name as it will appear to customers. - **Company Website URL**: Link to your official website. - **Company Description**: A brief overview of your company and offerings. - **Company Logo**: Upload a logo (SVG or PNG format, up to 300px wide by 150px high, max 500KB). - **Support Contact Information**: Email and/or phone number for customer support. ![Add public profile form in the AWS Marketplace Management Portal](images/aws-aws-marketplace-seller-registration-guid-2.png) Completing your public profile allows you to list free products. To list paid or BYOL products, continue with the remaining steps. For the full AWS walkthrough, see [Register as a seller on AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/seller-account-registering.html). :::tip **Where will my public profile be visible?** When a buyer searches for your company in AWS Marketplace, there is a link to your public profile below your listing (for example, "By Acme Corp"). Clicking it opens your profile page, which shows your logo, a short company description, and all products listed under your company. ![Seller public profile page on AWS Marketplace](images/aws-account-setup-6.png) ::: ### Step 4: Submit your tax information AWS requires tax information to comply with regional tax laws before you can publish paid products. **Instructions:** 1. In the AWS Marketplace Management Portal, go to [Settings](https://aws.amazon.com/marketplace/management/seller-settings/). 2. Under **Tax Information**, click **Go to tax dashboard** and complete the tax interview: - **U.S. sellers**: Submit a W-9 form. - **Non-U.S. sellers**: Submit a W-8 form and provide VAT or GST registration numbers, if applicable. 3. If available, complete the **VAT Information** section with your relevant VAT details. The following fields are typically required: - **Federal tax classification**. Most companies are a `C Corporation`; others may be an `S Corporation`, `Partnership`, or `Limited liability company`. - **Business Name** and **Business Address**. - **EIN** (Federal Employer Identification Number). ![AWS Marketplace tax information form](images/aws-account-setup-4.png) :::warning Make sure your business location matches **exactly** in both the AWS Billing console and your tax submission. A mismatch will block you from publishing paid listings. ::: For the full AWS walkthrough, see [Provide tax information to AWS](https://docs.aws.amazon.com/marketplace/latest/userguide/provide-tax-information.html). ### Step 5: Add your banking and disbursement information To receive payments from AWS, you must provide valid banking details. You must complete the tax information step first. **Add a bank account:** 1. In the AWS Marketplace Management Portal, go to [Settings](https://aws.amazon.com/marketplace/management/seller-settings/account). 2. Under **Payment Information**, select **Add Bank Account** and provide your details: - **U.S. Bank Account**: Enter your ACH-enabled account information. - **Non-U.S. Bank Account**: Provide your SWIFT code and account details. - **Hyperwallet**: If you don't have a U.S. bank account, you can register for a virtual U.S. bank account through Hyperwallet. The following fields are typically required: - **Bank account address** — the address on your company bank account. - **Bank account holder name** — in most cases, your company's legal name. - **Routing Number** - **Account Number** ![AWS Marketplace banking information form](images/aws-account-setup-5.png) **Set your disbursement preference:** After your bank account is added, configure how and when AWS sends your funds. Under **Settings > Payment Information**, click **Add disbursement** and fill out these sections: - **Disbursement Currency Info** — Select the currency you want to receive disbursements in. Only one currency can be associated per disbursement method. - **Disbursement Bank Account Info** — Select the bank account you added previously. UK bank accounts may not appear for disbursements in AUD, JPY, or USD; use an alternate account in those cases. - **Disbursement Schedule** — Choose **Daily** (disbursements occur automatically as they become available, requires a positive balance) or **Monthly** (a fixed day of the month, 1–28). Click **Save** to finalize your disbursement method. :::warning Creating a new disbursement schedule **overwrites** any previously created schedule. ::: For the full AWS walkthroughs, see [Provide bank account information](https://docs.aws.amazon.com/marketplace/latest/userguide/provide-bank-information.html) and [Set disbursement preferences](https://docs.aws.amazon.com/marketplace/latest/userguide/set-disbursement-preferences.html). ### Step 6: Complete KYC verification (if required) Know Your Customer (KYC) verification is required if you plan to: - Sell to buyers in Europe, the Middle East, or Africa (EMEA) - Receive disbursements for South Korea transactions - Use a UK-based bank account **Instructions:** 1. In the AWS Marketplace Management Portal, go to **Settings** and open the **Know Your Customer (KYC)** tab. 2. Start the KYC compliance process and provide the required information: - **Company Details**: Legal name, registration number, and address. - **Beneficial Ownership**: Information about individuals who own or control the company. - **Supporting Documents**: Upload documents such as business registration certificates and identification proofs. 3. Submit the information for verification. You can optionally add secondary users who can manage KYC information and financial details; these users must also complete the KYC verification process. :::warning AWS reviews a submitted KYC application typically within 24 hours, but completing KYC end to end — gathering the documents and answering any follow-up requests from AWS — can take much longer: AWS's [global expansion guide](https://aws.amazon.com/marketplace/partners/seller-journey/global-expansion) puts it at approximately **2–3 months**. If this applies to you, start early so it doesn't delay your go-live date. ::: For the full AWS walkthrough, see [Complete the Know Your Customer (KYC) process](https://docs.aws.amazon.com/marketplace/latest/userguide/complete-kyc-process.html). ### Step 7: Verify your bank account To finalize your registration and start receiving disbursements, verify your bank account. 1. In the AWS Marketplace Management Portal, go to **Settings**. 2. Under **Payment Information**, select **Update banking information**. 3. Choose the bank account you provided earlier. 4. Click **Verify** and follow the instructions to upload a recent bank statement that matches your account details. 5. Submit the information for verification. ### Confirm your seller status Once all the required steps are complete — public profile set up, tax and banking information submitted, and your disbursement method configured — your AWS Marketplace account status updates automatically. In the AWS Marketplace Management Portal, the status changes from **Public Free products** to **Publish Paid and Free products** (displayed in green). ![AWS Marketplace account status showing Publish Paid and Free products](images/aws-aws-marketplace-seller-registration-guid-3.png) ### Create an IAM Admin user (recommended) The root user has unrestricted access to all resources in an AWS account and should only be used for activities that require root credentials, such as billing or managing accounts through AWS Organizations. Following the principle of least privilege, create an **Admin user** in an Admin group and use it to operate your AWS account. 1. Sign in to the AWS Management Console and navigate to the **IAM service**. ![IAM service in the AWS console](images/aws-how-to-create-an-iam-admin-user-in-aws-1.png) 2. Under **Access management** on the IAM dashboard, go to **Users**. ![IAM Users page](images/aws-how-to-create-an-iam-admin-user-in-aws-2.png) 3. On the Users page, click **Add users**. ![Add users button on the IAM Users page](images/aws-how-to-create-an-iam-admin-user-in-aws-3.png) 4. Provide a user name and check **Enable console access**. Select the appropriate options under Console password, then click **Next**. ![IAM user details form](images/aws-how-to-create-an-iam-admin-user-in-aws-4.png) 5. (Optional) If you don't already have an Admin group, click **Create group**. If you do, skip to step 8. ![Create group option](images/aws-how-to-create-an-iam-admin-user-in-aws-5.png) 6. Provide a name for the Admin group and select the **AdministratorAccess** policy under Permissions policies. ![Selecting the AdministratorAccess policy](images/aws-how-to-create-an-iam-admin-user-in-aws-6.png) 7. Click **Create user group** to create the Admin group. ![Create user group](images/aws-how-to-create-an-iam-admin-user-in-aws-7.png) 8. Select the Admin group to add the user to, then click **Next**. ![Add user to the Admin group](images/aws-how-to-create-an-iam-admin-user-in-aws-8.png) 9. Adding tags is optional but recommended. Add tags as appropriate, then click **Create user**. ![Create user with tags](images/aws-how-to-create-an-iam-admin-user-in-aws-9.png) 10. Save or securely share the sign-in details for the Admin user, then click **Return to users list**. ![Save Admin user sign-in details](images/aws-how-to-create-an-iam-admin-user-in-aws-10.png) 11. In the Users list, confirm the Admin user has been created and added to the Admin group. ![Admin user created and added to the group](images/aws-how-to-create-an-iam-admin-user-in-aws-11.png) AWS sends updates about your registration — approvals, rejections, requests for more information — to your AWS account's root user email address, not the email of whoever is currently signed in. Check under **Settings → Notifications** in the AWS Marketplace Management Portal if you're not sure which email that is. If AWS rejects a step, reply from that same root email address, since some AWS teams only process requests from it. If you've already passed KYC, avoid editing your information unless AWS asks — submitting a change sends your KYC back under review. **Need help?** For seller registration, verification, or product review issues, submit a request through [AWS Partner Central Support](https://docs.aws.amazon.com/marketplace/latest/userguide/getting-support.html). For AWS account or billing issues, open a case in the AWS Support Console. :::tip **Phase 0 complete when:** your public profile, tax information, and bank account are all verified, and your KYC and bank verification are complete if they apply to you. ::: ## Phase 1: Get access to the Fours Console Before you can connect your cloud marketplaces or begin implementation, you'll need access to the Fours Console. In this phase, you'll create your organization, wait for approval, and invite the teammates who will participate in your marketplace implementation. **Estimated time:** About 10 minutes of hands-on setup, plus 1 to 2 business days for organization approval. 1. Go to [Fours Console](https://console.suger.io) and sign up using your company email address. If your company is new to Fours, click **Create New Organization**. 2. Your organization stays in a **Pending Approval** state until the Fours team approves it — send a quick message in your shared Slack channel once you've created it so we can track your onboarding and process the approval. Once approved, you'll get a confirmation email. Approval typically takes 1 to 2 business days; if you haven't heard back after 2, reach out in your Slack channel. 3. Once approved, invite the teammates who will participate in the implementation — see [Invite Your Team](/get-started/account/#invite-your-team). The person who created the organization automatically becomes its first **Admin**. Adding everyone early helps prevent delays later when configuring integrations, creating listings, testing, and sending offers. We recommend starting with: | Area | Recommended roles | | --- | --- | | AWS Marketplace | AWS Console Full Admin | | Business stakeholders | Sales Ops · Finance · Deal Desk · Marketplace Ops | :::tip **Phase 1 complete when:** your organization has been approved and the people involved in your marketplace implementation have access to the Fours Console. ::: ## Phase 2: Connect to AWS Marketplace and submit your first listing Now it's time to connect your AWS Marketplace seller account to Fours and create your first product listing. **Estimated time:** ~20 minutes for the integration, ~1-2 hours to create your listing, plus ~2 weeks for AWS's review. ### Step 1: Connect with AWS Marketplace Creating an IAM role is a security-sensitive action, so make sure the person completing this step has permission to create IAM roles and approve IAM changes in CloudFormation — otherwise the setup may fail or remain incomplete. If your security team restricts AWS permissions, some resources may need to be configured manually instead of automatically; that's expected for locked-down AWS environments, not a Fours issue. Follow [AWS Marketplace Integration](/aws-marketplace/integration/) to connect your account, configure required services such as Marketplace Data Feeds (MDFS), and verify the integration is working. ### Step 2: Create, test, and submit your listing Before creating your listing, decide your selling approach — public pricing, private offers, or both. If you plan to negotiate every sale through a private offer, keep in mind that AWS requires at least one publicly priced dimension above $0.00; a common approach is a high placeholder public price with a note asking interested buyers to contact your sales team for a private offer. Also decide your fulfillment URL — where AWS sends customers immediately after they subscribe. Use your own if you already have a signup page (AWS validates this during review, so custom implementations may need extra troubleshooting if something doesn't behave as expected); use Fours' hosted fulfillment URL if you don't have one, since it's already designed to meet AWS's requirements. Either way, AWS requires a successful test purchase before approving your listing. Follow [List Product](/aws-marketplace/list-product/) to create your product in Fours, configure pricing, complete the required test purchase, and submit for AWS review. Review timelines vary — see that page's [FAQ](/aws-marketplace/list-product/#faq) for current estimates, and leave extra time if you're working toward a launch date, since AWS may request revisions first. ### Optional: request the "Deployed on AWS" badge If your buyers negotiate AWS spend commitments (Enterprise Discount Programs or Private Pricing Addendums), they'll usually want their purchase to count toward that commitment — and only products with the **"Deployed on AWS"** badge qualify. It doesn't affect your ability to list or sell; skip this if your buyers don't care about spend commitments. To qualify, your product's entire application and control plane need to run on AWS (the only exceptions are CDNs, DNS, and corporate identity providers) — you submit an architecture diagram through the AWS Marketplace Management Portal for AWS to review. Your listing just needs to exist (even in `Limited` status from Step 2 above), not be publicly live yet, so it's worth submitting early to leave time for any AWS feedback. See [Deployed on AWS Badge](/aws-marketplace/deployed-on-aws-badge/) for the full requirements and submission steps. :::tip **Phase 2 complete when:** your listing has been submitted and its status is `Published` / `Public` in both AWS Marketplace and the Fours Console. ::: ## Phase 3: Go live & test with a private offer Once your listing is approved, confirm it's live and validate the buyer experience end to end before working with real customers. **Estimated time:** Less than 1 hour once your listing has been approved. 1. In the Fours Console, go to **Product**, open your AWS product, and confirm the status is **Public**. Copy the **Marketplace URL** and open it in an incognito window — if it loads, your product is live. 2. Create and accept a private offer using an account you control, to verify your private offer workflow, fulfillment, and entitlement processing all work before inviting real customers. See [Create an AWS Marketplace Private Offer](/aws-marketplace/create-private-offer/). This is a different test than the one in Phase 2 — that one confirms your public listing accepts a purchase; this one confirms your private-offer workflow end to end. Don't skip either — it's much easier to catch issues here than after a real customer transacts. :::tip **Phase 3 complete when:** your test private offer has been successfully accepted and you've confirmed the end-to-end purchase flow works as expected. ::: ## Phase 4: CRM integration (optional) If your team uses Salesforce or HubSpot, connect it to Fours to manage private offers and co-sell opportunities more efficiently. Skip this phase if you use neither — check with your Fours contact if you're unsure whether CRM integration is included in your subscription. - Salesforce (~1 hour, requires a Salesforce Admin) — lets your sales team send private offers and share opportunities with AWS without leaving Salesforce. See [Integrate Salesforce with Fours](/integrations/salesforce/#overview). - HubSpot (~10 minutes, requires access to install apps and grant CRM permissions in HubSpot) — enables co-sell capabilities from the Fours console. See [Integrate HubSpot with Fours](/integrations/hubspot/). :::tip **Phase 4 complete when:** your CRM is connected to Fours and the integration is ready to use. ::: ## Phase 5: Co-Sell setup (optional) If you plan to co-sell with AWS and your Fours subscription includes co-sell capabilities, complete this phase — otherwise, skip it. AWS co-selling lets you share opportunities with your AWS account team so they can collaborate with you throughout the sales cycle. **Estimated time:** ~30 minutes, plus any time needed to complete AWS eligibility requirements. 1. Confirm your organization meets the eligibility requirements for AWS ACE (AWS's co-sell program) — see the [APN Customer Engagements Program](https://aws.amazon.com/partners/programs/ace/). 2. Connect your AWS co-sell integration — see [Integrate AWS ACE with Fours](/integrations/aws-partner-network-api/). Your Fours contact will then help you configure field mapping so opportunities sync correctly between your CRM and AWS ACE. :::tip **Phase 5 complete when:** your AWS co-sell integration is connected and opportunity syncing has been configured. ::: ## You're live — what's next Congratulations! You're ready to start transacting with customers through AWS Marketplace using Fours. From here, your focus shifts from setup to day-to-day marketplace operations — creating private offers, managing agreements, tracking revenue, and growing your marketplace business. ### Self-serve customers Your onboarding is complete; post in your dedicated Slack channel or email [support@suger.io](mailto:support@suger.io), and expect a response within 1 business day. ### SMB / Mid-Market / Enterprise customers Your Customer Success Manager will schedule a post-launch check-in to help you plan your growth strategy, manage private offers, set up co-sell workflows, and answer product questions. ## Important links :::important Bookmark these — you'll want quick access to them once you're live. ::: | Resource | Where | | --- | --- | | Your AWS listings, offers, and payment settings | [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/) | | Create a private offer | [AWS Marketplace Private Offers](/aws-marketplace/create-private-offer/) | | Check if an invoice has been paid | [Revenue Records](/revenue/revenue-records/) | | Refunds and cancellations | [AWS Marketplace Refunds and Cancellations](/aws-marketplace/refunds-cancellations/) | --- Source: https://doc.fours.com/aws-marketplace/integration/ # Integration Grant Fours the necessary permissions to manage your AWS Marketplace on your behalf, no more no less. --- ## Overview :::info Concurrent Agreements Support Fours already supports **AWS Marketplace Concurrent Agreements** for SaaS products. This feature allows buyers to make multiple purchases of the same product within a single AWS account, enabling multi-team procurement, mid-term expansions, and repeat purchases without requiring workarounds. **EventBridge is required** for Concurrent Agreements support. You must enable EventBridge integration to handle multiple active subscriptions. Starting **June 1, 2026**, AWS requires Concurrent Agreements support for all new SaaS products. ::: 1. Visit the [Integration page](https://console.suger.io/settings?tab=integrations) of `suger console`. > AWS Marketplace integration page in Fours Console 2. Click the button `CONNECT` and redirect to new browser tab. It will automatically start a `AWS CloudFormation Stack` on your AWS account to create an `IAM role` for Fours to access & manage your `AWS Marketplace` on your behalf. :::tip - Contact support@suger.io for the Fours AWS Account ID to fill the stack field `AccountId`. - Fulfill the field `MdfsS3BucketName` with `suger-mdfs-s3-bucket-{your-aws-account-id}`. ::: > AWS CloudFormation stack creating IAM role for Fours 3. Check the box of `I acknowledge that ...` and click button `Create stack`. 4. Wait for a few minutes, the `AWS Marketplace` integration status will be updated as `VERIFIED`. > AWS Marketplace integration status showing Verified :::tip - You may need to click the button `VERIFY` to verify whether the `AWS marketplace` integration works correctly. ::: :::tip Need to open AWS support cases? That's a separate **AWS Support** integration — see [AWS Support Cases](/aws-marketplace/support-cases/). ::: ## Edit Integration You can edit the integration to update the following fields: - **Enable Entitlement End Soon Notification**: When enabled, specify the number of days (10-60) before an entitlement ends to trigger notifications. Fours will send an initial notification when AWS Marketplace entitlements approach ending, followed by reminders every 5 days. To configure recipients, follow the [email notification configuration guide](/settings/email-notification/#configuration) and add the scope `END_SOON.ENTITLEMENT`. :::warning The IAM role identity is fixed after creation The **IAM Role ARN** and **External ID** that identify the role Fours assumes are set once, when the integration is created, and cannot be changed by editing it. Fours restores them from the stored integration on every update and ignores anything sent in their place, so a saved edit never repoints Fours' access at a different role. If you genuinely need to move the integration to another IAM role — for example after re-deploying the CloudFormation stack into a different AWS account — delete the integration and connect it again. The same rule applies to the AWS Billing, AWS S3, and AWS Partner Central (ACE) integrations. Rotating an access key, or changing the bucket and region on an S3 integration, is still an ordinary edit. ::: ## Delete Integration The AWS integration can be deleted like all other integrations. Once the deletion icon is clicked & confirmed, the integration info will be deleted immediately & permanently from Fours. No time window or methods to recover. When more than one AWS account is connected (see [Multiple Integrations](#multiple-integrations)), each account's card is deleted on its own and the other accounts keep working. Deleting the default account makes the oldest remaining account the default. The deleted account's products, offers and entitlements stay in Fours, but Fours can no longer sync them or act on them, because no connected account owns them. Remove that account's `SugerAccessMarketplaceStack` from its own AWS account as described below. :::warning - To completely delete the `IAM Role` created for Fours, please visit your [AWS CloudFormation](https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2), and delete the stack `SugerAccessMarketplaceStack`, which will remove all resources including `IAM Role` created for Fours. - If you also deployed the standalone EventBridge stack from [Manual EventBridge Setup](#manual-eventbridge-setup), delete that stack as well (in `us-east-1`) to remove the EventBridge Connection, API Destination, Rule, and IAM Role it created. ::: ## Multiple Integrations You can connect more than one AWS Marketplace seller account to the same Fours organization — for example, when a subsidiary sells from its own AWS account. Each account is its own AWS Marketplace integration with its own card on the [Integrations page](https://console.suger.io/settings?tab=integrations), and each product, offer and entitlement belongs to the account it was listed or sold under. ### Add another AWS account Connect your first account with the `CONNECT` button, as described in [Overview](#overview). Once an account is connected, you add the next one from its card: 1. On the Integrations page, open your AWS Marketplace card's **⋯** menu and choose **Add Integration**. 2. The **Add another AWS Marketplace account** dialog lists the accounts that are **Already connected**, then walks you through three steps: 1. **Sign in to the AWS account you want to add.** Open the AWS console in another browser tab and switch to that seller account. The CloudFormation stack is created in whichever account is signed in, so this step decides which account gets connected. 2. **Give it a name (optional).** Up to 100 characters, shown next to the account ID. 3. **Create the access role.** Click **Open CloudFormation**, fill in the stack fields the same way as for your first account (see step 2 of [Overview](#overview)), and click **Create stack**. 3. Return to the Fours tab once the stack is created. While the dialog is open, Fours checks for the new account automatically for up to 10 minutes and confirms **Connected AWS account** with the account's ID. If no new account is detected within 10 minutes, the dialog says so. The usual cause is a stack created in an account that is already connected, which changes nothing. Check the stack's status in the AWS CloudFormation console, then click **Retry**. ```d2 shape: sequence_diagram you: "You" console: "Fours Console" aws: "The AWS account\nyou are adding" suger: "Fours" you -> aws: "Sign in to that seller account in your browser" you -> console: "Add Integration,\nname it (optional), Open CloudFormation" console -> aws: "Open the CloudFormation quick-create page" you -> aws: "Create stack" aws -> suger: "The stack reports the new access role" second: "if this is your second account" { suger -> suger: "Attach your first account's products, offers,\nentitlements and referrals to its account ID,\nand make it the default" } console -> suger: "Check for the new account (up to 10 minutes)" suger -> console: "A new card showing the account's AWS account ID" { style.stroke-dash: 4 } ``` When your second account is connected, every AWS Marketplace card shows the line **AWS account** followed by that account's 12-digit ID, and your first account is marked **Default**. The products, offers, entitlements and referrals you already had stay with that first account. A third or later account is simply added alongside. When you create a SaaS or Professional Services product while more than one account is connected, choose its account in the **AWS Marketplace Integration** field — see [Create the AWS Marketplace Product](/aws-marketplace/list-product/#step-2-complete-basic-information). ### Choose the default account The default account is the one Fours uses when a request does not say which account it is for: - **A buyer arrives from a fulfillment URL with no `partnerId`** — typically a listing created before you connected your second account. If the default account can't read the buyer's registration token, Fours tries your other connected accounts before failing the signup. See [Set up your fulfillment URL](/aws-marketplace/list-product/#set-up-your-fulfillment-url). - **An API request doesn't name an account** — for example, creating a product without a `partnerID`. To change the default, open the **⋯** menu on another account's card and choose **Set as default**. The option appears only while more than one account is connected, and only on accounts that are not already the default. :::tip Each account's card can be edited, verified or deleted on its own. See [Delete Integration](#delete-integration) for what happens to an account's objects when you delete it. ::: ## AWS IAM Policies Here is the list of AWS managed policies included in the `Suger Access IAM role`. | Policy Name | Description | | -------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `arn:aws:iam::aws:policy/AWSMarketplaceFullAccess` | This policy grants Fours full access to AWS Marketplace and related services, as well as access to Amazon EC2, AWS CloudFormation, and Amazon EC2 Systems Manager. | | `arn:aws:iam::aws:policy/AWSMarketplaceSellerFullAccess` | This policy grants Fours to manage your sales (product listings, offers, entitlements & metering) on marketplace. | | `SugerAccessMarketplacePolicy` | This policy grants Fours necessary-only permissions on `AWS s3` & `AWS SNS` to configure & access your [AWS Marketplace Commerce Analytics Service](https://docs.aws.amazon.com/marketplace/latest/userguide/commerce-analytics-service.html#permissions-for-commerce-analytics) and [AWS Marketplace Data Feeds Service](https://docs.aws.amazon.com/marketplace/latest/userguide/data-feed-service.html). | :::info None of these policies grant access to the AWS Support API; the AWS Support integration uses its own IAM role. See [AWS Support Cases](/aws-marketplace/support-cases/). ::: ## Minimum-Permission Deployment (Optional) The default CloudFormation template requests broad permissions — including `iam:CreateRole`, the `events:*` family, and the AWS-managed `AWSMarketplaceFullAccess` / `AWSMarketplaceSellerFullAccess` policies — so that Fours can automatically provision and maintain the IAM role, EventBridge rule, connection, and API destination required for AWS Marketplace event delivery. With the default template, no further manual work is needed on your side, and new AWS Marketplace capabilities are picked up automatically as we add support. If your security team prefers a tighter blast radius, **we recommend using a dedicated AWS seller account exclusively for the Fours integration**. A dedicated account is the cleanest way to isolate Fours' access from the rest of your AWS footprint and is what we suggest for most enterprise customers. If a dedicated seller account is not an option, please contact [Fours Support](mailto:support@suger.io) for a **minimum-permission deployment package**. We can provide a CloudFormation template scoped down to only the actions Fours needs at deploy time. A minimum-permission role cannot create the EventBridge resources that deliver AWS Marketplace events, so set them up yourself with [Manual EventBridge Setup](#manual-eventbridge-setup) below. :::warning Trade-offs of the minimum-permission deployment - AWS Marketplace ships new features regularly, and most of them depend on additional IAM actions. With the default template, Fours picks them up transparently. With the minimum-permission template, support for those new features may temporarily break in your account. - Each time we add support for a new AWS Marketplace capability that requires extra permissions, you will most likely need to **redeploy an updated minimum-permission CloudFormation stack** before the capability works for you. We will reach out when this is needed, but onboarding new functionality will not be as seamless as with the default template. ::: ### Manual EventBridge Setup If your Fours Access IAM role does not grant `iam:CreateRole` / `iam:CreatePolicy` / `iam:PutRolePolicy` (for example, because you are running the minimum-permission template, or your security team disallows Fours from creating IAM resources on your behalf), Fours cannot auto-provision the IAM role and EventBridge resources required for [Concurrent Agreements](#overview) and other event-driven capabilities. In that case, deploy the standalone CloudFormation template below — under an AWS principal that *does* have IAM and EventBridge admin permissions — in **the same AWS account and region** as your AWS Marketplace listings. It creates the four resources Fours needs: - An EventBridge **Connection** with API-key auth (header `x-suger-api-key`): `aws-marketplace-event-connection-manual-${OrgId}`. - An EventBridge **API Destination** pointing at `${Endpoint}/public/aws/eventbridge/webhook/orgId/${OrgId}`: `aws-marketplace-event-api-destination-manual-${OrgId}`. - An **IAM Role** that lets EventBridge invoke the API Destination: `event-bridge-invoke-role-manual-${OrgId}`. - An EventBridge **Rule** matching `aws.marketplacecatalog` and `aws.agreement-marketplace` events and routing them to the API Destination: `aws-marketplace-event-rule-webhook-manual-${OrgId}`. Every resource name ends in `-manual-${OrgId}`, your Fours organization ID, so the stack never collides with the resources that Fours auto-provisions, and several Fours organizations can each deploy their own stack in the same AWS account. When Fours sets up EventBridge for a new integration itself, it creates a separate rule, connection, API destination and invoke role for each Fours organization, so two Fours organizations that sell from the same AWS account each receive their own events. An integration whose EventBridge setup already exists keeps it as it is. #### Parameters | Parameter | Description | | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `AuthId` | Your organization's **auth ID**, on the [settings page](https://console.suger.io/settings). Sent on every forwarded event as the `x-suger-api-key` header — it is the only value the webhook accepts, so do not generate a separate API key here. | | `Endpoint` | Fours API base URL: `https://api.suger.cloud`. | | `OrgId` | Your Fours organization ID, visible on the Fours Console settings page. | :::tip - Deploy the stack in **`us-east-1`**. AWS Marketplace SaaS events are emitted from `us-east-1`, and cross-region delivery is not supported by the default rule. - Treat `AuthId` like any other production secret — set the parameter with `NoEcho` enabled (already the default in the template) and avoid committing it to source control. ::: #### Template ```yaml AWSTemplateFormatVersion: '2010-09-09' Description: Forward AWS Marketplace events to Suger via EventBridge API Destination Parameters: AuthId: Type: String NoEcho: true Description: Your Suger organization's auth ID (sent as the x-suger-api-key header) Endpoint: Type: String Description: Suger API base URL, e.g. https://api.suger.cloud AllowedPattern: ^https?://.+ OrgId: Type: String Description: Suger organization ID AllowedPattern: ^[A-Za-z0-9-]+$ Resources: SugerMarketplaceConnection: Type: AWS::Events::Connection Properties: Name: !Sub 'aws-marketplace-event-connection-manual-${OrgId}' Description: API key auth for Suger event ingestion AuthorizationType: API_KEY AuthParameters: ApiKeyAuthParameters: ApiKeyName: x-suger-api-key ApiKeyValue: !Ref AuthId SugerMarketplaceApiDestination: Type: AWS::Events::ApiDestination Properties: Name: !Sub 'aws-marketplace-event-api-destination-manual-${OrgId}' Description: Suger marketplace event ingestion endpoint ConnectionArn: !GetAtt SugerMarketplaceConnection.Arn HttpMethod: POST InvocationEndpoint: !Sub '${Endpoint}/public/aws/eventbridge/webhook/orgId/${OrgId}' # Trust policy uses constructed rule ARN (not !GetAtt) to break the cycle # Rule.Targets -> InvokeRole -> Rule. SugerEventBridgeInvokeRole: Type: AWS::IAM::Role Properties: RoleName: !Sub 'event-bridge-invoke-role-manual-${OrgId}' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: sts:AssumeRole Condition: ArnEquals: aws:SourceArn: !Sub 'arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/aws-marketplace-event-rule-webhook-manual-${OrgId}' Policies: - PolicyName: event-bridge-iam-policy-invoke-api-destination PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: events:InvokeApiDestination Resource: !GetAtt SugerMarketplaceApiDestination.Arn SugerMarketplaceEventRule: Type: AWS::Events::Rule Properties: Name: !Sub 'aws-marketplace-event-rule-webhook-manual-${OrgId}' Description: Captures AWS Marketplace events and forwards to Suger State: ENABLED EventPattern: source: - aws.marketplacecatalog - aws.agreement-marketplace Tags: - Key: SugerVersion Value: '3' Targets: - Id: suger-api-destination Arn: !GetAtt SugerMarketplaceApiDestination.Arn RoleArn: !GetAtt SugerEventBridgeInvokeRole.Arn Outputs: RuleName: Description: EventBridge Rule name. Enter this in the Suger console to register the setup. Value: !Ref SugerMarketplaceEventRule ConnectionArn: Description: EventBridge Connection ARN Value: !GetAtt SugerMarketplaceConnection.Arn ApiDestinationArn: Description: EventBridge API Destination ARN Value: !GetAtt SugerMarketplaceApiDestination.Arn EventRuleArn: Description: EventBridge Rule ARN Value: !GetAtt SugerMarketplaceEventRule.Arn InvokeRoleArn: Description: IAM Role ARN used by the rule to invoke the API Destination Value: !GetAtt SugerEventBridgeInvokeRole.Arn ``` #### Register the rule in Fours Once the stack is created, tell Fours which rule you made, so that it tracks your setup instead of trying to create its own: 1. On the [Integrations page](https://console.suger.io/settings?tab=integrations), open the **⋯** menu on your AWS Marketplace card and choose **Edit**. 2. At the bottom of the **Edit Integration** dialog, find **Register your EventBridge rule**. The section appears only while Fours has no EventBridge rule recorded for this integration. 3. Enter the name of your rule in `us-east-1` — the `RuleName` value on the stack's **Outputs** tab, `aws-marketplace-event-rule-webhook-manual-${OrgId}` if you deployed the template above unchanged — and click **Register existing setup**. The registration is saved as soon as you click the button, and the section disappears. It records the setup; it does not prove that events flow — the [Verify](#verify) steps below do that. A registered setup is yours, and Fours never changes it: its hourly setup leaves the rule, the rule's tags, the connection and its API key alone, and it never re-authorizes the connection. Fours only reads the setup — once right after you register it, then in the daily [delivery health check](#eventbridge-delivery-health). Those reads need the read-only actions `events:ListRules`, `events:ListConnections` and `events:ListApiDestinations` on the Fours Access IAM role, so keep them there. Fours finds the connection and the API destination from the rule's name: whatever follows `aws-marketplace-event-rule-webhook` in the rule name must also follow `aws-marketplace-event-connection` and `aws-marketplace-event-api-destination` in theirs, as `-manual-${OrgId}` does in the template above. If you create the resources by hand instead, keep that pattern, or the health check cannot find them. ```d2 shape: sequence_diagram you: "You" aws: "Your AWS account\n(us-east-1)" console: "Fours Console" suger: "Fours" you -> aws: "Deploy the EventBridge stack: connection,\nAPI destination, IAM role and rule" you -> console: "Edit → Register your EventBridge rule\n→ Register existing setup" console -> suger: "The rule name" suger -> suger: "Record the setup as yours: never modified" suger -> aws: "Read the rule, connection and API destination\n(read-only)" events: "every AWS Marketplace event" { aws -> suger: "Rule → API destination → Fours webhook,\nwith your auth ID as x-suger-api-key" } daily: "once a day" { suger -> aws: "Read-only delivery health check" } ``` #### Verify 1. Wait for the stack to reach `CREATE_COMPLETE`. 2. Trigger any AWS Marketplace action that emits an event — see the table below (for example, publish a private offer or have a buyer accept one). 3. On the [Integrations page](https://console.suger.io/settings?tab=integrations) of the Fours Console, scroll down to the **Auditing Events** table and confirm a new entry appears with **Source = `AWS_EVENT_BRIDGE`**. The **Action** column shows which AWS event arrived (e.g. `Offer Released`). ![Auditing Events table showing entries with Source AWS_EVENT_BRIDGE](images/aws-manual-eventbridge-auditing-events.png) The AWS Marketplace activities that produce EventBridge events: | AWS Marketplace activity | Auditing event action | | ----------------------------------------------------------------- | ------------------------------------------------------------ | | A private offer is published (released to the buyer) | `Offer Released` | | A change set finishes — AWS applied, rejected, or cancelled it (for example a listing edit saved in Fours or in the AWS Marketplace Management Portal) | `Change Set Succeeded` / `Change Set Failed` / `Change Set Cancelled` | | A buyer accepts an offer — a purchase agreement is created | `Purchase Agreement Created - Manufacturer` / `- Proposer` | | An existing agreement is amended (e.g. expansion, renewal) | `Purchase Agreement Amended - Manufacturer` / `- Proposer` | | An agreement ends (expires or is cancelled) | `Purchase Agreement Ended - Manufacturer` / `- Proposer` | | An agreement is approaching its end date | `Purchase Agreement Ending - Manufacturer` / `- Proposer` | | An agreement is approaching an automatic renewal | `Purchase Agreement Renewal Upcoming - Manufacturer` / `- Proposer` | | The terms of an automatic renewal are settled | `Purchase Agreement Renewal Terms Finalized - Manufacturer` / `- Proposer` | | The license backing an agreement (entitlements) is updated | `License Updated - Manufacturer` | | The license backing an agreement is deprovisioned | `License Deprovisioned - Manufacturer` | The last three arrive only for agreements carrying [pre-authorized auto-renewal](/aws-marketplace/pre-authorized-auto-renewal/) terms, and they drive three entitlement email scopes you can route on the **Email notification** settings: `RENEW.ENTITLEMENT`, `AUTO_RENEW_OFF.ENTITLEMENT`, and `RENEW_SOON.ENTITLEMENT`. **Offer Released** also brings in offers you did not create in Fours — one released from the AWS Marketplace Management Portal or the AWS Marketplace Catalog API, or a renewal offer AWS generates. Fours syncs such an offer as soon as the event arrives instead of waiting for the hourly sync. The offer's product must already be in Fours. All three change-set outcomes are recorded in Auditing Events, but only a succeeded change to a SaaS listing refreshes that listing in Fours — see [Edits made in the AWS Marketplace Management Portal](/aws-marketplace/update-listing/#edits-made-in-the-aws-marketplace-management-portal). :::tip Fours filters out only the `AWS API Call via CloudTrail` detail type. Change-set events are recorded, so editing a listing — in Fours or in the AWS Marketplace Management Portal — also works as a test: once AWS finishes processing the change, a `Change Set Succeeded` or `Change Set Failed` entry appears. ::: :::note The warning "Event Bridge Rule is not setup correctly." clears once you register the rule Until you [register the rule](#register-the-rule-in-fours), the AWS Marketplace integration card in the Fours Console shows a warning icon with the message **"Event Bridge Rule is not setup correctly."**. The card shows it whenever Fours has no EventBridge rule recorded for the integration, and it does not affect event delivery. ![AWS Marketplace integration card showing the Event Bridge Rule warning](images/aws-manual-eventbridge-warning.png) Registering the rule records it, and the warning goes away. Either way, the verification steps above (events arriving in the Fours Console) are the source of truth for whether delivery works. ::: If events do not appear within a few minutes, check the EventBridge rule's **Monitoring** tab in the AWS Console for `FailedInvocations` and contact [Fours Support](mailto:support@suger.io) with the failure details. #### Cleanup When you remove the AWS Marketplace integration from Fours, also delete this stack from CloudFormation (in `us-east-1`) to clean up the EventBridge Connection, API Destination, Rule, and IAM Role it provisioned. See [Delete Integration](#delete-integration) for the standard cleanup steps. ## Enable Concurrent Agreements Concurrent Agreements let your buyers hold multiple active agreements for the same AWS Marketplace product at the same time. That lets your sales team run expansion deals, multi-team procurement, and repeat purchases without waiting for a buyer's existing contract to renew or expire. Starting **June 1, 2026**, AWS requires all new SaaS listings to support Concurrent Agreements. Fours handles the backend work for you — your responsibility is to confirm your EventBridge integration is active, submit the opt-in request to AWS, and complete a short validation test. :::info Concurrent Agreements also changes how usage metering works for the product — see [Usage Metering for AWS Concurrent Agreements](/metering/usage-metering/#usage-metering-for-aws-concurrent-agreements). ::: :::important If your product's **Product Type** is `Container`, Fours does not report its usage — with or without Concurrent Agreements. Container and AMI products report their own usage from inside the running container or instance with AWS's `MeterUsage` API, and Fours' metering API refuses usage for those listings with HTTP 400. See [AMI & Container Products](/metering/usage-metering/#ami--container-products). ::: ### Does this apply to you? | Your situation | What you need to do | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | New SaaS listing created after June 1, 2026 | Concurrent Agreements is already enabled. Confirm EventBridge is active in Fours, then you are done. | | Existing SaaS listing created before June 1, 2026 | Concurrent Agreements is not enabled automatically. Complete all steps in this section. | | Professional Services listing | Concurrent Agreements is enabled automatically by AWS. No action needed. | | Product Type is `Container` | Fours does not meter Container listings, with or without Concurrent Agreements; the product reports its own usage with `MeterUsage`. See [AMI & Container Products](/metering/usage-metering/#ami--container-products). | ### Step 1: Confirm EventBridge is active Concurrent Agreements require EventBridge to be enabled on your AWS integration in Fours. EventBridge is what lets Fours receive the `LicenseArn` parameter that uniquely identifies each concurrent agreement. Without it, the feature won't work. 1. Open the **Fours Console** and click **Settings**. 2. Click **Integrations**, then find the **AWS Marketplace** card. 3. Click **Details** on your AWS integration. ![AWS Marketplace integration details in the Fours Console](images/aws-enable-aws-marketplace-concurrent-agreem-1.png) 4. Make sure that `agreementEventBridgeEnrolled` = `true`. ![Integration details showing agreementEventBridgeEnrolled set to true](images/aws-enable-aws-marketplace-concurrent-agreem-2.png) If EventBridge is not enabled, complete the [Manual EventBridge Setup](#manual-eventbridge-setup) before continuing. ### Step 2: Submit the opt-in request to AWS Existing SaaS listings require a support request to AWS before Concurrent Agreements can be enabled. 1. Open the [AWS Marketplace Contact Us form](https://aws.amazon.com/marketplace/management/contact-us/). 2. Fill in the form with the following selections: - **Primary email address** — your preferred contact email - **Which AWS Marketplace Catalog are you inquiring about** — Commercial Marketplace - **What do you need help with** — Product Configuration / Integration - **Select a subcategory** — Concurrent Agreements Support 3. Under **Provide more details about your request**, include: - **Seller Account ID** - **Fours Seller Name** - **AWS Product ID(s)** for all public listings you want to migrate. To find these, open the **Fours Console**, go to **Products**, select your AWS Cloud Partner, and filter by **Status = Public**. - **Number of active agreements** on each listing - **Why you're opting in rather than creating a new listing** — AWS requires a brief explanation 4. Also request that AWS allow-list the Fours test buyer account for validation testing. Contact [Fours Support](mailto:support@suger.io) for the test buyer account ID. 5. Click **Message support** to send your request. ### Step 3: Create test private offers AWS requires validation testing before completing the opt-in. For each pricing model your products use, create a test [private offer](/aws-marketplace/create-private-offer/) in Fours directed at the allow-listed Fours test buyer account. Configure each test offer with: | Field | Value | | ------------- | -------------------------------- | | Offer Name | Test Concurrent Agreement Offer | | Buyer | Fours test buyer account ID | | Contract Term | 1 month | | Commit Amount | $1 | | Terms | Standard AWS Marketplace Terms | Create one offer per pricing model you use: - **Contract** — fixed commitment - **Usage** — usage-based only - **Contract + Usage** — commitment with usage overage ### Step 4: Accept the test offer and report usage 1. Have your AWS admin accept each test private offer from the allow-listed buyer account. 2. If your product uses usage-based pricing, submit a small test usage record via the **Fours Console** to validate your metering pipeline: | Field | Value | | --------------- | ---------------------------- | | Date | Current date | | Usage Dimension | Your product's usage dimension | | Quantity | 1 | This generates approximately $0.01 in usage, which AWS uses to confirm your metering is working correctly. ### Step 5: AWS completes the migration AWS reviews the test transactions to confirm that Concurrent Agreement events, entitlements, and usage reporting are all functioning correctly. Once validated, AWS completes the migration on their end and notifies you. After migration, your team can immediately: - Create multiple private offers for the same product and buyer simultaneously. - Run expansion deals and mid-term upgrades without waiting for renewal dates. - Support multi-team procurement with independent pricing and terms per agreement. ## EventBridge Delivery Health EventBridge is how AWS Marketplace tells Fours that an offer was released, an agreement was created, or an entitlement changed. If that delivery path breaks, nothing errors out loudly — events simply stop arriving, and your offers and entitlements quietly go stale. Fours closes that blind spot with a daily health check. Once a day it reads the delivery path straight out of your AWS account — the EventBridge rule, the connection, the API destination — and records the result on the AWS Marketplace integration. ### The four health states | State | What it means | What Fours does | | --- | --- | --- | | `OK` | The full delivery path was verified healthy. | Nothing. | | `INACTIVE` | The infrastructure is healthy, but no marketplace event has arrived in the last **30 days**. | Advisory only. Many low-activity accounts legitimately receive very few events, so this never interrupts you. | | `DISCONNECTED` | A part of the delivery path is verified broken, so marketplace events are being dropped. | Fours Support is alerted; the hourly sync re-authorizes a deauthorized connection automatically. | | `N_A` | EventBridge was never set up for this integration. | Nothing. | ```d2 direction: down check: "Daily health check\nreads the delivery path from your AWS account" setup: "EventBridge set up\nfor this integration?" { shape: diamond } path: "Rule, connection and\nAPI destination all healthy?" { shape: diamond } fresh: "An event received\nin the last 30 days?" { shape: diamond } na: "N_A" disconnected: "DISCONNECTED\nevents are being dropped" inactive: "INACTIVE\nadvisory only" ok: "OK" check -> setup setup -> na: "no" setup -> path: "yes" path -> disconnected: "no" path -> fresh: "yes" fresh -> inactive: "no" fresh -> ok: "yes" ``` ### Why the path was reported DISCONNECTED The check records a specific reason, which Fours Support uses to point you at the fix: | Reason | What broke | | --- | --- | | `NOT_CONFIGURED` | The integration exists but EventBridge was never set up. | | `ACCESS_DENIED` | Fours cannot assume the integration IAM role, or is denied the EventBridge read APIs — usually a deleted CloudFormation stack. | | `RULE_MISSING` | The EventBridge rule no longer exists. | | `RULE_DISABLED` | The rule exists but is disabled. | | `CONNECTION_MISSING` | The API-key connection no longer exists. | | `CONNECTION_DEAUTHORIZED` | AWS deauthorized the API-key connection, so events are dropped. Fours re-authorizes the connection automatically on its next hourly sync. | | `API_DESTINATION_MISSING` | The API destination no longer exists. | | `API_DESTINATION_INACTIVE` | The API destination exists but is not active. | | `NO_RECENT_EVENTS` | The infrastructure is healthy, but no event has arrived recently. This is the `INACTIVE` reason. | :::tip If you set EventBridge up manually rather than through the Fours CloudFormation stack, the health check sees your setup only once you [register the rule](#register-the-rule-in-fours). Until then it reports `N_A`, because Fours has no rule recorded for the integration. After you register it, the check reads your rule, connection and API destination by name without changing them — and if the Fours IAM role is not allowed to read EventBridge resources in your account, it reports `ACCESS_DENIED`. Either way, the [Verify](#verify) steps — real events landing in the **Auditing Events** table — are the source of truth. Fours re-authorizes a deauthorized connection only on a setup it created. If the connection of a setup you registered is deauthorized, re-authorize it yourself: update the connection in the EventBridge console with the same API key, your organization's auth ID. ::: ## Marketplace Commerce Analytics Service (MCAS) The Commerce Analytics Service accesses the Amazon S3 bucket and Amazon SNS topic after you configure the service with the ARN for the topic and name of the bucket. To enable MCAS, please follow the steps below. For more details, see the [documentation](https://docs.aws.amazon.com/marketplace/latest/userguide/commerce-analytics-service.html#technical-implementation-guide). 1. Log in to the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/) with the AWS account you use to manage your AWS Marketplace products. 2. Ensure you have the [necessary IAM permissions](https://docs.aws.amazon.com/marketplace/latest/userguide/commerce-analytics-service.html#technical-implementation-guide) to enroll in the AWS Marketplace Commerce Analytics Service. 3. Navigate to the [Commerce Analytics Service enrollment page](https://aws.amazon.com/marketplace/management/cas/enroll). - Select `Use an existing IAM role` - Select IAM role as the default `MarketplaceCommerceAnalyticsRole` - Set S3 bucket name `suger-mcas-s3-bucket-{aws-account-id}` - Set SNS topic ARN `arn:aws:sns:us-east-1:{aws-account-id}:suger-mcas-sns-topic` - Click the `Enroll` button :::warning - If you have enrolled the MCAS before, please contact us to get custom configuration. We will update the IAM policy of the IAM role `MarketplaceCommerceAnalyticsRole` to support the right S3 bucket & SNS topic. ::: 4. On the AWS Marketplace Management Portal, record the Role Name ARN in the success message. :::note If AWS reports that your account is not set up for the Commerce Analytics Service — it is not registered as a Marketplace seller, or has no MCAS subscription — Fours turns on **MCAS Sync Disabled** for the integration and stops requesting MCAS data, because retrying cannot succeed. Once you have completed the enrollment above, edit the integration and turn **MCAS Sync Disabled** off so the sync resumes. ::: ## Marketplace Data Feeds Service (MDFS) To get the full structured, up-to-date product billing and customer information from AWS Marketplace, it is highly recommended to set up the [Data Feeds Service](https://docs.aws.amazon.com/marketplace/latest/userguide/data-feed-service.html). Follow the below steps: :::warning - If you have set up the field `MdfsS3BucketName` with `suger-mdfs-s3-bucket-{your-aws-account-id}` in the previous cloud formation stack of AWS Marketplace integration, please skip the following **step 1** & **step 2** since the MDFS S3 bucket and KMS have been created. ::: 1. Go to the [Data Feed Configuration page](https://aws.amazon.com/marketplace/management/reports/data-feed-configuration). 2. Click `Configure with Cloud Formation`, a new page with stack template will be opened. Type in the `Stack name` with `mp-data-feed` (don't change this name since it is recognized by Fours service), and the `S3BucketName` with an unique S3 name `suger-mdfs-s3-bucket-{aws-account-id}`. Then click button `Create stack`. :::warning - The `stack name` must be `mp-data-feed`. Otherwise, Fours service won't recognize. - The `S3BucketName` must be `suger-mdfs-s3-bucket-{aws-account-id}`. Otherwise, suger service won't have permissions to access. - The stack must be running in the AWS region `us-east-1`, not other regions. ::: > CloudFormation stack setup for Marketplace Data Feeds Service 3. Once the upper Cloud Formation stack is 'CREATE_COMPLETE', find the `S3 Bucket ARN` (for example: `arn:aws:s3:::suger-mdfs-s3-bucket-{aws-account-id}`) and the `KMS Key ARN` (for example: arn:aws:kms:us-west-2:awsAccountId:key/keyId), and input them to the [Data Feed Configuration page](https://aws.amazon.com/marketplace/management/reports/data-feed-configuration). Click buttion `Submit`. 4. Fours service take all the rest of setup and cron data sync pipeline. ### FAQ ### My Security team asked about the need for a KMS access policy. How does Fours use KMS in our account? The KMS access is for MDFS integration, which syncs revenue data and buyer information (company name, address, and email domain). AWS requires all S3 buckets for marketplace revenue and buyer reports to be encrypted by a KMS key. This KMS key is created via the cloud formation template provided by AWS. [More details can be found here](/aws-marketplace/integration/#marketplace-data-feeds-service-mdfs). Fours doesn’t require general access to your KMS resources; it is only limited to the one related to the MDFS integration. ## Set up Tax & Banking Info AWS marketplace requires the seller/ISV to provide valid Tax & Banking Info before selling paid or BYOL (bring your own license) products. Please visit the [setting page](https://aws.amazon.com/marketplace/management/seller-settings/account) of your AWS marketplace management portal, and submit the tax information & banking information (to collect revenue from marketplace sales). ### Tax Information The following fields for tax information are required: 1. **Federal tax classification**. Most companies are `C Corporation`, and the others may be `S Corporation`, `Partnership` or `Limited liability company`. 2. **Business Name** and **Business Address** 3. **EIN** (Federal Employer Identification Number) > Tax information form with EIN field ### Banking Information The following fields for banking information are required: 1. **Bank account address**, the address on your company bank account. 2. **Bank account holder name**, in most cases, it is your company legal name. 3. **Routing Number** 4. **Account Number** > Banking information form with routing and account number ## AWS Payment Flow When a customer purchases your product on AWS Marketplace, the transaction follows AWS's billing and payment structure: ![AWS Marketplace payment flow overview](images/aws-aws-payment-flow-1.png) 1. The customer subscribes to or purchases your product. 2. AWS generates an invoice and adds it to the customer's consolidated AWS billing. 3. The customer pays AWS according to their payment terms (for example, net 30, 45, or 60 days). 4. Once AWS receives the payment, it disburses to you based on your selected disbursement cycle (daily or monthly). :::info - AWS disburses payments to sellers **only after** receiving payment from the customer. For example, if a customer on net 60 terms buys your product today, payment is due to AWS in 60 days, and only after AWS receives it will you be paid. ::: ### Disbursement cycles Choose your disbursement cycle in the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/seller-settings/account) under **Payment Information**: - **Daily** — AWS pays as soon as payment becomes available. - **Monthly** — AWS pays on a fixed day (1–28) of each month. ### Currency and exchange rates Offers are created in **USD**, customers are billed in their **local currency**, and AWS uses **Bloomberg exchange rates** to convert. See [Multi Currency](/aws-marketplace/create-private-offer/#multi-currency) for creating offers in non-USD currencies. ### Track expected payment in Fours To check when AWS is expected to receive payment from the buyer: 1. Go to the **Entitlement** menu. 2. Click the entitlement in question. 3. Open the **Revenue** tab. 4. Scroll to the **Due Date** column in the revenue table — this shows the estimated date the buyer will pay AWS. :::tip - The **Due Date** is not the date the money is disbursed to your account. AWS processes disbursement only **after** this payment is received. ::: ### Common payment issues Payments can be delayed by incorrect account permissions, declined credit cards, or customer billing setup issues. Make sure your customers have a valid payment method and a correctly configured AWS account. If payment is delayed beyond the expected due date, open a support case on the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/contact-us/). ## FAQ ### Who do I receive the payment from? Payment will always be deposited into your registered bank account. To check your registered bank account, visit the [Settings section](https://aws.amazon.com/marketplace/management/seller-settings/account) on AMMP > Payment Information. ### How much listing/transaction fee does AWS take? Listing fees depend on the type of listing, TCV of the offer, and type of offer. The document below is an official document by AWS that covers the fee structure for all scenarios. https://docs.aws.amazon.com/marketplace/latest/userguide/listing-fees.html ### When is the customer billed? AWS bills the customer based on three ways: 1. Date of subscription acceptance (upfront billing) 2. Custom payment schedule (private offers built by flexible payment scheduler) 3. Metered usage on the second and third day of the month for the prior month’s usage ### When will I receive money from AWS? Every customer has agreed to net payment terms with AWS — commonly net 30, 45 or 60, and net 0 for credit cards. Once a customer receives the bill, they must pay the amount within the agreed terms. You can also override that per offer: a private offer can carry its own **Buyer net payment term** of Net 15, 30, 45, 60, 90, or 120 days. See [Buyer net payment term](/aws-marketplace/create-private-offer/#buyer-net-payment-term). A longer term delays when AWS collects, and therefore when AWS disburses to you. Every seller has a disbursement cycle, which can be set up under settings. There are two cycles: daily and monthly. You can receive the money as soon as the AWS receives it or on a specific date every month. To check your registered bank account, visit the [Settings section](https://aws.amazon.com/marketplace/management/seller-settings/account) on AMMP > Payment Information > Update Banking Information > Disbursement Preference. ### Do I need to charge and remit taxes separately? This depends on the buyer's country. In countries such as the USA, where the marketplace is responsible for collecting and remitting taxes, this function will be handled by AWS itself. In other countries, such as France, the Seller must collect the tax manually. AWS's video [AWS Marketplace Tax Rules](https://youtu.be/qaBDxNiZkho) explains how AWS assesses tax and how it affects invoicing. AWS's [Tax Help for Sellers](https://aws.amazon.com/tax-help/marketplace-sellers/) covers taxes on different product types, the countries supported, and the process. ### What should we do if there is a delay in receiving payments from AWS? You can open a ticket with AWS through the [AWS Marketplace contact form](https://aws.amazon.com/marketplace/management/contact-us/). ### How to process refunds? You can process a full or partial refund to the buyer by submitting AWS's [refund request form](https://aws.amazon.com/marketplace/management/support/refund-request). You can request a refund even when the buyer has not yet paid the invoice. In the additional comments section, mention that the charges should be waived if they are unpaid. ### Can I invoice a customer in their currency? You will create private offers in Dollars ($) as a seller. AWS will, in turn, check the buyer's currency based on the account ID and the payment settings and then bill them in their currency. AWS uses exchange rates published by Bloomberg every day. See AWS's [list of supported currencies](https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-paying-for-products.html#supported-currencies) for the current set. ### We have an offer that was accepted, but the payment transaction failed. Is there a way to reprocess the transaction? If a private offer acceptance fails due to an issue with the customer's payment method/account, the customer can try accepting the same private offer again after it is fixed. This time, it should go through. The offer they initially accepted didn't generate any entitlement because it wasn't processed. They can use the same offer link to accept it again, and it should work this time. ### We have an offer that the customer has tried to accept three times, and we get an acceptance email and then immediately get a cancellation email. Is this a typical payment issue? Is there something that you'd advise us to tell the customers to solve this? There are three main reasons why an offer acceptance might fail: 1. The person trying to accept the offer doesn't have the proper permission to complete that transaction. 2. Their credit card operator declined the transaction, or they have not correctly set up their account for payment. 3. AWS can reject them from transacting if they have not paid their latest billing. Usually, it's a problem with the customer's credit card or with their payment account in general. You can contact the customer to have them help you verify the transaction. We recommend asking in the discovery if they are on an Invoice or Credit Card with AWS. If they are on a Credit Card, tell them they need to make sure that their Bank knows this transaction is about to be processed so that it does not get rejected, as often Credit Card companies will reject due to the size of the transaction as possible fraud. --- Source: https://doc.fours.com/aws-marketplace/product-types/ # Product Types Before you build a listing, decide what type of product you're selling on AWS Marketplace and whether you can create it directly in Fours. --- ## Overview Your product type determines how buyers deploy your software, what AWS requires from you technically, and how long it takes to go live. This page explains each AWS Marketplace product type, how they differ, and which ones you can create directly in Fours. ## Product Types at a Glance AWS Marketplace supports several product types. The right one depends on how your software is delivered to buyers. | Product type | How it's delivered | Can be created in Fours? | AWS reference | | --- | --- | --- | --- | | **SaaS** | Hosted by you; buyers access it through your environment | ✅ Yes | [SaaS-based products](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-products.html) | | **Professional services** | Human-delivered engagements (consulting, training, implementation, etc.) | ✅ Yes | [Professional services products](https://docs.aws.amazon.com/marketplace/latest/userguide/proserv-products.html) | | **AMI** | Pre-installed software image buyers launch in their own AWS account | ⚠️ Create in AWS first, then it syncs to Fours | [AMI-based products](https://docs.aws.amazon.com/marketplace/latest/userguide/ami-products.html) | | **Container** | Packaged container images buyers deploy in their own AWS environment | ⚠️ Create in AWS first, then it syncs to Fours | [Container-based products](https://docs.aws.amazon.com/marketplace/latest/userguide/container-based-products.html) | | **Machine learning** | Algorithms or model packages deployed via Amazon SageMaker | ❌ Not supported in Fours | [Machine learning products](https://docs.aws.amazon.com/marketplace/latest/userguide/machine-learning-products.html) | | **AI agent** | Conversational agents deployed as SaaS or containers | ⚠️ Depends on the deployment type | [AI agent products](https://docs.aws.amazon.com/marketplace/latest/userguide/ai-agents-tools.html) | :::info The "How it's delivered" descriptions are summarized from the [AWS Marketplace product delivery guide](https://docs.aws.amazon.com/marketplace/latest/userguide/product-preparation.html#product-delivery). Refer to that page for the full AWS definitions. ::: ## Reporting usage through Fours Product type also decides whether you can report metered usage to AWS through Fours. **Container and AMI listings cannot.** AWS meters those products from the buyer's own AWS environment, so there is no external usage to send. On a container or AMI entitlement, the **Report Usage** and **Report Usage in Batch** buttons on the Metering page are greyed out, and their tooltip reads *"Reporting usage externally is not supported for container and AMI product listings."* SaaS, professional services, and machine learning entitlements are unaffected — report usage for those in Fours as normal. :::note If the buttons are greyed out on a listing that is not container or AMI Fours fails closed. When it cannot yet tell what kind of listing an entitlement belongs to — most often a channel partner (CPPO) entitlement whose product has not finished syncing — the buttons stay disabled and the tooltip reads *"Unable to verify whether external usage reporting is supported for this AWS listing."* Give the product sync a moment and reload; if it persists, contact [support@suger.io](mailto:support@suger.io). ::: ## What's Next Once you've decided on your product type, your next step is choosing your pricing model. See [Choose the right AWS Marketplace pricing model](/aws-marketplace/pricing-model/). --- Source: https://doc.fours.com/aws-marketplace/pricing-model/ # Pricing Model Choose the right AWS Marketplace pricing model before you build your listing. --- ## Overview Your pricing model determines how AWS bills your buyers, how revenue is recognized, and what flexibility buyers have after purchasing. It's also one of the few decisions that can't be easily changed later. AWS Marketplace supports several SaaS pricing models, plus different options for Professional Services, AMI, and container products. You can choose only one pricing model for each of your SaaS [product listing](/aws-marketplace/list-product/). :::warning - You can't change your pricing model after publishing your listing to Limited. If you later decide you chose the wrong model, you'll need to create a new listing and migrate future transactions to it. Take the time to choose carefully before submitting your listing. ::: ## SaaS Pricing Models AWS supports four pricing models for SaaS products: | Pricing model | Best for | Buyer commitment | | :-------------------------- | :-------------------------- | :----------------------------------- | | Subscription | Usage-based products | None | | Contract | Seat-based or tiered products | Fixed-term commitment | | Contract with subscription | Commitment plus overages | Fixed commitment plus metered usage | | Free | Freemium or open-source products | None | ### Subscription (Pay-As-You-Go) Buyers pay for what they use each month, with no commitment and no upfront cost. You, as the ISV/Seller, are billed based on the metering records you send to AWS Marketplace. All charges must be measured and reported every hour from the software deployed in the buyer's account. Usage is calculated and billed monthly, using the same mechanism as AMI-based AWS Marketplace offerings. You define what you're charging for using pricing dimensions, such as GB of data processed, API calls, active users, or compute hours. Your application reports usage to AWS so AWS can calculate charges. For example, imagine you sell a log monitoring platform and charge $0.10 per GB of logs ingested. A customer who ingests 500 GB in January is billed $50; if they ingest 1,200 GB in February, they're billed $120. The bill changes based on actual consumption. An example of a Subscription pricing model is shown below: | Dimension API Name | Dimension Description | Price per Dimension | | :----------------- | :----------------------------------- | :------------------ | | compute_service | 2 CPU, 8GB RAM per hour as one unit | $0.1 | | storage_service | 1GB per hour as one unit | $0.04 | | network_volume | 1GB as one unit | $0.2 | :::info - **Good fit if** your product's value scales with usage, and buyers prefer flexibility over cost predictability. ::: :::danger - A buyer can cancel their subscription to your SaaS subscription product at any time, with no commitment or cancellation restriction. The moment they cancel, you have exactly one hour to report their final usage. After that, AWS stops accepting records for that customer and billing ends. - If a buyer indicates that they want to cancel through your product, direct the buyer to AWS Marketplace. To guarantee there will be no future charges, buyers should confirm the cancellation with AWS Marketplace. ::: _To learn more, see [Pricing for SaaS subscriptions](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-subscriptions.html)._ ### Contract (Upfront Commitment) Buyers commit to a fixed quantity for a set period (1, 2, or 3 years) and pay upfront or in installments. The buyer initiates a purchase of your software and enters into an agreement with you, which entitles them to a specified quantity of use of your SaaS product. There is no usage metering — AWS validates that the customer has an active entitlement, and your application grants access accordingly. AWS Marketplace bills your buyers upfront or by the payment schedule that you define, based on the contract between you and your buyers. You may define several plans with multiple billing terms, and buyers select one during procurement. Buyers can also change plans within the contract term. For example, imagine you sell a project management platform with three plans: `Basic` (up to 25 users) for $2,000/year, `Professional` (up to 100 users) for $6,000/year, and `Enterprise` (unlimited users) for $15,000/year. A buyer who selects `Professional` commits to a one-year agreement worth $6,000. Depending on how the offer is structured, AWS can collect the full amount upfront or through scheduled payments. An example of a Contract pricing model is shown below: | Contract API Name | Dimension Description | Billing Term | Price per Contract Term | | :------------------- | :---------------------------------------------- | :----------- | :---------------------- | | data_service | process & storage streaming data | 1 Month | $2,000 | | premium_data_service | Premium plan to process & storage streaming data | 1 Month | $4,000 | | data_service | process & storage streaming data | 6 Months | $10,000 | | data_service | process & storage streaming data | 12 Months | $18,000 | Buyers on a Contract can: - ✅ Upgrade to a larger commitment during the term - ✅ Purchase additional capacity - ❌ Cancel or downgrade mid-term - ✅ Renew or change plans at the end of the contract :::info - **Good fit if** your buyers want budget certainty and your product has clear tiers or seat-based pricing. ::: _To learn more, see [Pricing for SaaS contracts on AWS](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-contracts.html)._ ### Contract with Subscription (Combined) Based on the SaaS contract pricing model, for each pricing dimension in your contract you can let customers pay as they go for additional usage above their contract. You can also add dimensions without contract prices that customers only consume by paying as they go. Buyers commit to a baseline amount, then pay for usage beyond that commitment. For example, imagine you sell a data pipeline tool. A buyer commits to a contract that covers 1 TB of data processed per month — that's their prepaid commitment, and they pay for it upfront. In a month where they process 1.4 TB, the extra 0.4 TB is billed at a metered per-GB rate on top of their contract. Fours tracks usage against the committed amount automatically: it consumes the prepaid commitment first, then only reports the true overage to AWS for billing, so the buyer is only charged extra when they actually exceed their commitment. :::info - **Good fit if** your buyers want a predictable baseline cost but their usage genuinely varies month to month. ::: :::danger - For Contract or Combined pricing, buyers can upgrade a contract to one of a higher value (for example, higher quantities or higher-value entitlements) except for longer durations. Buyers are given a prorated credit for their existing contract. Buyers can't decrease the size of their existing contract — they can only decrease the size at renewal, or cancel their renewal. ::: _To learn more, see [Pricing for SaaS contracts on AWS](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-contracts.html)._ ### Free Buyers use your product at no cost. Your product is listed in AWS Marketplace and buyers can subscribe normally, but all pricing dimensions are set to $0.00. AWS tracks subscriptions and entitlements, but no revenue is collected through the marketplace. :::info - **Good fit if** you're listing a freemium tier, open-source tool, or developer product where you want marketplace distribution without charging through AWS. ::: _To learn more, see [SaaS product pricing in AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-pricing-models.html)._ ## Professional Services Pricing Professional Services products use a different pricing structure than software listings. Instead of usage dimensions, you create **service packages**, such as: - 50-hour implementation package - Security assessment engagement - Premium onboarding package - Gold support package Professional Services transactions are completed through private offers. You can also configure **variable payment schedules**, allowing buyers to agree on a total contract value upfront and pay against project milestones over time. This works particularly well for consulting, implementation, migration, and advisory services. To learn more, see [Professional services products on AWS](https://docs.aws.amazon.com/marketplace/latest/userguide/proserv-variable-payments.html). ## AMI and Container Pricing Models AMI and container products use a different set of pricing options, since buyers run the software themselves inside their own AWS accounts. For the same reason, AWS meters these products from the buyer's environment, so you cannot report usage for them through Fours — see [Reporting usage through Fours](/aws-marketplace/product-types/#reporting-usage-through-fours). To learn more, see: - [AMI product pricing on AWS](https://docs.aws.amazon.com/marketplace/latest/userguide/pricing-ami-products.html) - [Container products pricing on AWS](https://docs.aws.amazon.com/marketplace/latest/userguide/pricing-container-products.html) ## Pricing Best Practices Before publishing your SaaS listing, think about how you'll sell your product over time, not just today. ### If You Only Plan to Sell Through Private Offers You still need to configure public pricing. AWS requires every SaaS listing to include at least one pricing dimension priced above **$0.00**, and buyers must be able to subscribe using your public listing. Pricing dimensions can't be limited to private offers only. If you don't want buyers purchasing at your public rate, a common seller practice is to set a high placeholder price (for example, **$100,000/year**) and include your contact information in the product description so buyers know to request a private offer instead. When a buyer accepts a private offer, AWS bills them using the negotiated private offer price, not the public price. ### Add Placeholder Usage Dimensions Before Publishing If you're creating a Contract or Contract with subscription listing, add any usage dimensions you might need later before publishing, even if you initially price them at **$0.01**. AWS locks your pricing dimensions after the listing is published. Adding placeholder dimensions now gives you the flexibility to bill for future overages, custom usage, or one-off charges through private offers without creating a new listing. For example, if you publish a usage dimension at **$0.01**, you can later charge any amount by adjusting the quantity reported to AWS. Without that placeholder dimension, you'd need to publish an entirely new listing to introduce that billing option. ## What's Next Once you've chosen your pricing model, you're ready to prepare your product listing. See [Create and publish an AWS Marketplace listing](/aws-marketplace/list-product/). --- Source: https://doc.fours.com/aws-marketplace/list-product/ # List Product Create, test, and publish your AWS Marketplace listing for SaaS, Professional Services, AMI, and Container products. --- ## Overview AWS Marketplace allows buyers to purchase products using their AWS committed spend, streamlining procurement and accelerating sales. With Fours, you can list and manage your products effortlessly — we handle the complexity, so you can focus on growth. **Product vs Listing** - **In Fours**, a Product is the configuration object you manage in the Fours Console, including pricing, fulfillment, and marketplace settings. - **In AWS Marketplace**, a Product is the listing that buyers see and purchase. One Fours Product maps to one AWS Marketplace listing. ### Prerequisites Make sure the following are in place before creating your listing in Fours: - **AWS Marketplace** — you must be a registered seller on AWS Marketplace. See [Register as an AWS Marketplace seller](/aws-marketplace/self-serve-onboarding/#phase-0-become-an-aws-marketplace-seller). - **Fours** — you need **Admin** access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account). :::info Concurrent Agreements Support As of June 1, 2026, AWS requires all new SaaS listings to support **Concurrent Agreements**, which lets enterprise buyers make multiple purchases of the same product within a single AWS account (multi-team procurement, mid-term expansions, and repeat purchases). Because you're using Fours, the required API updates are handled for you automatically — you only need to confirm that your AWS EventBridge integration is active. See the [Integration guide](/aws-marketplace/integration) for setup details. Learn more in the [AWS Concurrent Agreements announcement](https://aws.amazon.com/about-aws/whats-new/2026/02/concurrent-agreements-february/). ::: --- ## Create the AWS Marketplace Product ### Step 1: Start a new product draft 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product), then click **+ New Product**. ![New Product button in the Fours Console](images/aws-create-and-publish-an-aws-marketplace-li-1.png) 2. Select **AWS Marketplace** as the **Marketplace**. ![Create a new product in the Fours Console](images/aws-create-and-publish-an-aws-marketplace-li-2.png) 3. Choose your **Product Type**: - [**SaaS (Software as a Service)**](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-getting-started.html) — software hosted on your infrastructure where buyers are granted access. This is the most common product type. - [**Professional Services**](https://docs.aws.amazon.com/marketplace/latest/userguide/proserv-products.html) — consulting services related to AWS products, such as implementation, premium support, or training. :::note AMI and Container products aren't shown in the dropdown because they must be built in your AWS account and submitted to AWS Marketplace directly for scanning and review. Once AWS approves and publishes them, Fours automatically syncs them for you. See [Listing AMI Products](#listing-ami-products) and [Listing Container Products](#listing-container-products) below. ::: ### Step 2: Complete Basic Information :::tip - **AI Autofill** — use the ✨ **AI Autofill** feature to generate initial descriptions, categories, and keywords. It's a starting point only and may make assumptions, so always review and adjust before saving. - **Special characters** — AWS Marketplace only accepts standard keyboard (ASCII) characters, plus © ® ™ and the currency symbols ¢ £ ¤ ¥; anything else blocks your draft from saving. Write descriptions in a plain text editor first to strip hidden formatting, and replace curly quotes and smart apostrophes (" " ' '), em/en dashes (—, –), ellipses (…), and bullet points (•) with plain equivalents (straight quotes, a hyphen -, and three dots ...). ::: Review and complete the following fields: - **AWS Marketplace Integration** — appears only when your organization has more than one AWS seller account connected (see [Multiple Integrations](/aws-marketplace/integration/#multiple-integrations)). Choose the account to list the product under; the product, and the offers you create for it, belong to that account. Each option shows the name you gave the account and its AWS account ID — ` ()` — or `AWS - MARKETPLACE - ` when the account has no name. - **Company Name** — must exactly match the name registered in your AWS Public Profile. Mismatches can cause your listing to be rejected. - **Product Title** — the public name buyers see. Use title case, keep it descriptive, and avoid marketing superlatives like "the best" or "the only." - **Product Category** — select up to 3 relevant categories to help buyers discover your product. [See the AWS product categories](https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-product-categories.html); the full list is in the Fours Console dropdown. - **Short Description** — 1–2 clear sentences focused on core value and keywords. Up to 1,000 characters is allowed, but anything past ~188 characters is hidden behind "Show more", so put important info upfront. - **Long Description** — short, readable paragraphs covering the customer problem, your solution, key features, and any technical prerequisites (integrations, compliance certifications, system requirements). Up to 5,000 characters, but only the first ~188 show before collapsing under "Show more". - **Company Logo** — upload in `.png` or `.jpg` with a white or transparent background, between 120 and 640 pixels, in a square (1:1) or wide (2:1) aspect ratio, matching the branding in your AWS Marketplace seller profile. - **Highlights 1–3 (at least 1 required)** — short, punchy bullet points focused on your product's primary benefits and differentiators. Each highlight can be up to 500 characters and is formatted as a single bullet. - **Search Keywords (up to 15)** — keywords or short phrases buyers might use when searching. Each can be up to 50 characters. Press **Enter, comma (,), or semicolon (;)** after each keyword to add it. Mix broad and specific terms. - **Resources (up to 3 files, required)** — link to content that helps buyers evaluate and deploy your product, such as user guides, API documentation, FAQs, or video tutorials. These appear under "Additional Support" on your listing. - **Support Details (required)** — include your support email, available hours (with time zone), and expected response time so buyers know how to reach you after purchase. - **EULA** — the legal contract between you and the buyer. Every AWS Marketplace listing must have one: - **AWS Standard Contract (SCMP)** — a pre-written contract widely accepted by enterprise legal teams. Choosing this speeds up procurement since many buyers have already pre-approved the SCMP internally. Learn more in the [AWS standardized license terms guide](https://docs.aws.amazon.com/marketplace/latest/userguide/standardized-license-terms.html). - **Custom EULA** — your own agreement uploaded as a PDF. Choose this if your legal team requires specific contract language. Every buyer's legal team must review it from scratch, which can add weeks to procurement. - For private offers, you always have the option to attach a specific agreement for that buyer. :::warning Avoid the following in your descriptions and highlights — they have a high chance of blocking your listing from going public: - **Dependency on a parent product without disclosure** — if your product only works as an add-on to another product, AWS requires you to state so explicitly and note that it has very limited utility without the parent (see the [AWS SaaS product guidelines](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-guidelines.html)). Leaving this out is a common rejection reason. - **Competitive claims** — avoid language that positions your product against a named competitor (e.g. "better than [competitor]"). - **Unverifiable statistics** — avoid specific performance or efficiency claims AWS reviewers can't validate (e.g. "reduces costs by 95%", "3x faster than the industry average"). ::: #### AI API Products Only enable the **AI API Product** toggle if you are listing an AI Agent, MCP Server, Knowledge Base, or Guardrail. When enabled, additional fields appear: - **Endpoint URL** — the public URL where your API receives requests. Must use HTTPS and be publicly accessible (e.g. `https://api.yourproduct.com/v1`). For MCP servers, use your MCP endpoint URL. - **Authorization Method** — how buyers authenticate. Choose **API Keys** for simplicity, or **OAuth** for enterprise buyers who need SSO or fine-grained access control. - **Type** — the category that best describes your product: AI Agent, MCP Server, Knowledge Base, Guardrail, or Other. See the [AWS AI agent products overview](https://docs.aws.amazon.com/marketplace/latest/userguide/ai-agents-tools.html) for definitions. - **API Usage Instructions** — a plain-English guide telling buyers how to start using your API after subscribing (authentication steps, endpoints, rate limits, error codes, and a link to your full documentation). Supports Markdown. - **API Specification** — optional but recommended, and required if you want your product to integrate with Amazon Bedrock AgentCore. Choose **OpenAPI**, then select or upload the file under **OpenAPI specification file upload**. Fours checks the file against Amazon Bedrock AgentCore Gateway's OpenAPI rules when you create the product, and again whenever you save an edit to its info or pricing or publish it (saving a draft does not check it). An incompatible file is refused right away instead of failing later inside AWS: a file that is not valid JSON gets *"spec must be valid JSON; YAML is not supported by Bedrock AgentCore Gateway:"* followed by the parser's detail, and a JSON spec that breaks a rule gets *"OpenAPI spec is not compatible with Bedrock AgentCore Gateway:"* followed by each problem to fix. The file must: - be **JSON** — the file picker also offers `.yml` and `.yaml`, but a YAML file is refused - be **1 MB** or smaller - use OpenAPI **3.0** or **3.1** — Swagger 2.0 is refused - list at least one server under `servers`, and give every server a URL whose protocol is `http` or `https`, in any letter case (a templated protocol such as `{scheme}://` is allowed and checked at run time) - give every operation an `operationId`, unique across the spec — Bedrock AgentCore uses it as the MCP tool name - leave out `oneOf`, `anyOf` and `allOf`, `callbacks`, response `links`, a top-level `webhooks` field, and a top-level `security` requirement (configure authentication in the Gateway instead) - use supported media types only: `application/json`, `application/xml`, `multipart/form-data` or `application/x-www-form-urlencoded` for request bodies, and `application/json` or `application/xml` for responses - avoid the `matrix`, `label` and `deepObject` parameter styles, and complex path serializers such as `{;id}`, `{?id}` or `{*}` - **API Integration Protocols** — optional. Select **MCP** if your product is an MCP server, or **A2A** if your agent communicates with other AI agents. Leave blank for a standard REST API. ### Step 3: Complete Pricing Information Pricing differs depending on product type. :::tip Not sure which pricing model fits your product? See [Choose the right AWS Marketplace pricing model](/aws-marketplace/pricing-model) — it covers all models with real-world examples before you set anything up. ::: #### SaaS AWS offers three pricing models for SaaS listings: Subscription, Contract, and Contract + Subscription Combined. **We recommend the Contract + Subscription Combined model for most SaaS listings**, even if you only plan to sell fixed contracts today. In the Fours Console this means filling out both the **Contract Commitment** and **Usage Metering** sections. There are two types of dimensions: - **Commit dimensions** — fixed packages buyers pay for upfront (e.g. a "Pro Plan" for 12 months). - **Usage dimensions** — pay-as-you-go charges based on consumption (e.g. extra hosts beyond their plan). Set up the following fields: **Contract Duration Options** — choose which contract lengths (1, 12, 24, or 36 months) are visible to buyers on your public AWS storefront. To sell annual contracts only, select just the 12-month option. The durations you select here determine which price fields appear when you add a commit dimension. **Contract Commitment** — a commit dimension is a fixed package or tier a buyer can purchase. You can add up to 200 dimensions per SaaS listing (see [Pricing for SaaS subscriptions](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-subscriptions.html)). For each dimension, click **+ Add dimension** and fill in: - **API Identifier** — an internal code that identifies the dimension in the billing system. Buyers never see it. Must be unique, all lowercase, no spaces, and 15 characters or less (e.g. `premium_tier` or `admin_user`). You can't change this once published. - **Display Name** — the name buyers see at checkout. Keep it under 24 characters (e.g. "Premium User Seat"). - **Description** — a short explanation of what this dimension includes. Keep it under 70 characters (e.g. "Access for one administrator user"). - **1 / 12 / 24 / 36 month price** (one per duration you selected) — **don't enter your real prices yet.** Leave all price fields at $0.01 for now. :::warning Before your listing can go live, AWS requires a mandatory end-to-end test purchase. If you enter a real price (like $1,200) at this stage, that test purchase will generate a real charge for that exact amount. You'll set your actual prices later, when you request to change your listing visibility from `Limited` to `Public`. When you do set real prices, remember that each price field represents the **total upfront cost for that duration**, not a monthly rate. For example, a tier costing $100/month should have a 12-month price of $1,200. ::: **Purchasing Options** — controls how buyers interact with your dimensions at checkout: - **Allow buyers to purchase multiple dimensions** — buyers can select more than one dimension and set quantities in a single purchase. Choose this for a-la-carte or seat-based models. _Example: a buyer purchases 5 Admin Seats and 50 Read-Only Seats at once._ - **Restrict buyers to a single dimension** — buyers must choose exactly one dimension per purchase. Choose this for strict, mutually exclusive tiers. _Example: a buyer must choose either the Basic Plan or the Pro Plan._ **Usage Metering** — usage dimensions define the pay-as-you-go charges for anything a buyer consumes beyond their base plan. Click **+ Add dimension** for each and fill in: - **API Identifier** — the internal code your software sends to AWS when reporting metered usage. Same rules as commit dimensions: lowercase, no spaces, unique (e.g. `extra_storage` or `overage_fee`). Only visible in billing reports, so it doesn't need to be reader-friendly, and it can't be changed after publishing. - **Display Name** — what buyers see on billing reports (e.g. "Extra Storage (GB)", "Additional Usage Fee"). - **Price Per Unit** — the amount charged each time one unit is consumed. **Leave all price fields at $0.01 for now** (same test-purchase reasoning as above). - **Description** — a short, user-friendly explanation of what triggers the charge (e.g. "Storage consumed beyond the base plan limit"). :::tip Always keep at least one catch-all usage dimension permanently priced at $0.01, even after your listing goes public. Because AWS locks all dimensions after publishing, this gives you a flexible way to bill for custom overages or edge cases later, simply by adjusting the quantity. ::: #### Professional Services Professional Services listings work differently — you don't set public pricing. Instead, you define the service packages or tiers you offer (dimensions), then attach custom pricing to those dimensions when creating a private offer for a specific buyer. All Professional Services products are sold through private offers, so pricing is always negotiated directly with the buyer. For each service package, click **+ Add dimension** (see [Pricing dimensions](https://docs.aws.amazon.com/marketplace/latest/userguide/proserv-product-details.html#proserv-pricing-dimensions)) and fill in: - **API Identifier** — an internal code that identifies the dimension. Buyers never see it. Must be unique, all lowercase, no spaces, and 15 characters or less (e.g. `migration` or `consulting_10h`). You can't change this once published. - **Display Name** — the name buyers see on the private offer checkout page (e.g. "Cloud Migration Assessment", "10 Hours Consulting"). - **Description** — a short explanation of what this service includes. Repeat for each service package you want to offer. ### Step 4: Save, Preview, and Create - **Save as Draft** — saves your progress in the Fours Console without submitting anything to AWS. - **Preview** — see exactly how your listing will appear on AWS Marketplace. - **Create** — submits your product draft to AWS. Your listing's status transitions from `Draft` to `Pending Create`, and finally to `Limited` visibility once AWS validation succeeds. --- ## Test and Publish Your SaaS Listing Once you click **Create**, your product enters `Limited` visibility. The listing is live on AWS but hidden from the public — only you and any allowlisted accounts can access it for testing. Add your test buyer accounts from the listing's **More actions → Manage Allowlisted Accounts** (see [Allowlist AWS accounts on a Limited listing](7.update-listing.md#allowlist-aws-accounts-on-a-limited-listing)). ### Set up your fulfillment URL When a buyer purchases your product on AWS, their browser is sent to Fours through the fulfillment URL. Fours receives the purchase information from AWS, syncs the entitlement, and immediately redirects the buyer to your signup experience. Two fulfillment URLs are involved: | Location | Purpose | | ---------------- | --------------------------------------------------------------------------- | | AWS Marketplace | Sends the buyer to Fours after purchase | | Fours Console | Configures the signup URL where buyers are redirected after Fours processes | #### Step 1: Choose your signup experience - **Option 1: Use your own signup page** — choose this if you already have a dedicated page where new users register or log in. Copy the link to your existing registration or login page. _Example: `https://your-company.com/signup`._ - **Option 2: Use Fours' hosted signup form** — if you don't have a custom signup page yet. First configure it in the Fours Console under **Settings → New Client Signup**, then click **Preview** and copy the URL from the browser address bar. ![Preview the Fours-hosted New Client Signup form](images/aws-create-and-publish-an-aws-marketplace-li-3.png) _Example: `https://api.suger.cloud/public/signup/newclient/YOUR_UNIQUE_ID`._ #### Step 2: Add the fulfillment URL to your product in Fours 1. Go to the **Products** page and open your AWS product. 2. Click **More actions**, then **Edit Fulfillment URL**. ![Edit Fulfillment URL from the product More actions menu](images/aws-create-and-publish-an-aws-marketplace-li-4.png) 3. Paste the URL from Step 1, then click **Save**. #### Step 3: Verify the AWS fulfillment URL When you create a product in Fours, the AWS fulfillment URL may be configured automatically in your AWS Marketplace listing. If it's not set correctly, update it manually using this format: `https://api.suger.cloud/public/signup/aws/orgId/YOUR_SUGER_ORG_ID?partnerId=` If the link doesn't work, try removing the `?partnerId=` suffix. ![AWS fulfillment URL field](images/aws-create-and-publish-an-aws-marketplace-li-5.png) To locate the fulfillment URL field in AWS Marketplace, see AWS's documentation on [updating fulfillment options](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-product-settings.html#update-fulfillment-options). If the URL was not added automatically: 1. Go to Fours, then click **Settings**. 2. Select **Organization**. Your Organization ID is displayed there. 3. Replace `YOUR_SUGER_ORG_ID` in the URL with that value, then copy it. ![Find your Organization ID in Fours Settings](images/aws-create-and-publish-an-aws-marketplace-li-6.png) 4. [Update the fulfillment URL in AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-product-settings.html#update-fulfillment-options). #### Step 4: Capture the entitlement ID (custom signup pages only) If you're using your own signup page, Fours appends a `sugerEntitlementId` parameter to the redirect URL. Your application must capture and store this value so the buyer account can be associated with the AWS Marketplace entitlement. See [Signup URL Redirect](/settings/signup-url-redirect) for implementation details. :::info If your organization has more than one AWS integration AWS issues a customer identifier that is unique per seller listing, not per AWS account. So one buyer AWS account that subscribes to products under two of your AWS integrations legitimately arrives with two different identifiers, and Fours keeps them as two buyer records rather than treating the second one as a duplicate of the first. Nothing extra to configure — but keep the `?partnerId=` value on the AWS-side fulfillment URL pointing at the integration that owns the listing, since that is what tells Fours which integration the purchase came through. This path is exercised during AWS's listing review, so an incorrect `partnerId` shows up there as a failed test purchase. A listing created before you connected your second AWS account usually has an empty `partnerId`. Fours resolves it to your [default account](/aws-marketplace/integration/#choose-the-default-account), and if that account can't read the buyer's registration token, it tries your other connected accounts before failing the signup. ::: ### Run a test purchase While your listing is in `Limited` visibility, AWS requires a full test purchase before you can submit for publishing approval. This validates your end-to-end fulfillment flow, confirms your fulfillment URL, and generates the active entitlement required for AWS listing approval. #### Step 1: Access AWS Marketplace 1. Open Fours, then click the [**Settings**](https://console.suger.io/settings) menu. 2. Go to the [**Integrations**](https://console.suger.io/settings?tab=integrations) tab. 3. Click **Console** on the **AWS Marketplace** card. ![AWS Marketplace Console access in Fours Integrations](images/aws-create-and-publish-an-aws-marketplace-li-7.png) 4. Open [AWS Marketplace](https://aws.amazon.com/marketplace/management/products/saas?#). #### Step 2: Subscribe to the listing 1. Click **SaaS products** from the **Build** menu. ![SaaS products in the AWS Marketplace Build menu](images/aws-create-and-publish-an-aws-marketplace-li-8.png) 2. Find and open the SaaS listing you need to test. 3. Click **View on AWS Marketplace**. ![View on AWS Marketplace](images/aws-create-and-publish-an-aws-marketplace-li-9.png) 4. Click **View purchase options** to open the subscription page. 5. Under **Contract details → Auto-renewal**, select **Do not automatically renew this contract**. ![Select do not automatically renew this contract](images/aws-create-and-publish-an-aws-marketplace-li-10.png) 6. Under **Pricing details**, select the required dimensions for the listing. :::warning Don't select a dimension with a real retail price, or you will be billed. ::: ![Select the $0.01 test dimension in Pricing details](images/aws-create-and-publish-an-aws-marketplace-li-11.png) 7. Click **Subscribe**. AWS shows a confirmation screen. 8. Click **Set Up Your Account**. You should be redirected to your signup page or the Fours-hosted New Client Signup form, confirming the fulfillment redirect works. For details on how this redirect works, see [Onboarding customers to your SaaS product](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-product-customer-setup.html). 9. Verify that you receive a confirmation email to create your account. #### Step 3: Check the entitlement AWS will not approve your listing without a successful test transaction on record. 1. Go to the Fours Console and open the product. 2. Go to the **Entitlements** tab. 3. Verify the test purchase generated an active entitlement. ![Active test entitlement in the Fours Entitlements tab](images/aws-create-and-publish-an-aws-marketplace-li-12.png) :::info What if the entitlement shows as cancelled instead of active? This usually means the test buyer's account had a payment failure. Make sure a valid payment method is set up on the AWS account you're testing with (see [Paying for products in AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-paying-for-products.html)), then run the test purchase again and confirm a new active entitlement was generated. ::: #### Step 4: Report usage (usage-based products only) If your product includes usage-based pricing, AWS requires a test usage record before approval to prove your metering integration works. 1. From the **Entitlements** tab, click the active test entitlement. 2. Go to the **Usage Metering** tab, then **+ Report Usage**. 3. Select the $0.01 generic test usage dimension you configured earlier, then enter a **Quantity** of `1`. 4. Click **Report**. This generates exactly $0.01 in usage to validate the metering connection. ### Publish the product and monitor review status :::warning Once your listing is live, price increases require a 90-day notice period before they take effect for existing subscribers. Plan your pricing carefully before publishing. See [Product pricing for AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/pricing.html). ::: #### Step 1: Update the pricing terms and publish 1. Go back to your product in the Fours Console. 2. Click **More actions**, then **Publish Product**. 3. Update your pricing terms — replace the $0.01 test prices with your actual retail prices. ![Update pricing terms before publishing](images/aws-create-and-publish-an-aws-marketplace-li-13.png) 4. Click **Save**. AWS reviews your listing for publication, which typically takes 2–4 weeks. :::info What if I only plan to sell through private offers? You still need to set a public price. Per the [AWS SaaS product guidelines](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-guidelines.html), pricing dimensions can't be limited to private offers only — buyers must be able to subscribe to any dimension on your public listing. A common practice is to set a high placeholder price (like $100,000/year) and direct buyers to your support contact for custom pricing. When a buyer accepts your private offer, they transact at the offer price, not the public rate. For usage dimensions you only use in private offers, set the public rate to $0.01 as a placeholder to keep the dimension available. ::: #### Step 2: Monitor the review status 1. Open Fours, click the [**Settings**](https://console.suger.io/settings) menu, and go to the [**Integrations**](https://console.suger.io/settings?tab=integrations) tab. 2. Click **Console** on the **AWS Marketplace** card. ![AWS Console access in Fours](images/aws-create-and-publish-an-aws-marketplace-li-14.png) 3. Open [AWS Marketplace](https://aws.amazon.com/marketplace/management/products/saas?#) and click **SaaS products** from the **Build** menu. ![SaaS products list in AWS Marketplace](images/aws-create-and-publish-an-aws-marketplace-li-15.png) 4. Find and open the SaaS product, then click the **Requests log** tab to view your submission history and status. To learn what each status means, see [managing change requests](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-product-settings.html#create-change-request). #### Step 3: Confirm your listing is live Once AWS approves your listing and sets it to `Public`: - **The direct listing URL is available immediately.** Confirm it's live by copying the URL from your product in Fours and opening it in an incognito window. ![Copy the direct listing URL from Fours](images/aws-create-and-publish-an-aws-marketplace-li-16.png) - **Search results may take up to a day to update.** If your listing still doesn't appear after a day, contact [AWS Marketplace Seller Support](https://docs.aws.amazon.com/marketplace/latest/userguide/getting-support.html). #### Step 4: Cancel the test entitlement Once your listing is live, cancel the test agreement to stop ongoing charges, prevent it from skewing your revenue reports, and keep your active entitlements clean. See [Handle AWS Marketplace refunds and cancellations](/aws-marketplace/refunds-cancellations). --- ## Test and Publish Your Professional Services Listing ### Review your listing Double-check all details, descriptions, and service tiers (dimensions) for accuracy. Remember, you can't change your API Identifiers once the listing is published. ### Publish the product and monitor review status 1. Go back to the Fours Console and open the product. 2. Click **More actions**, then **Publish Product**. AWS reviews the listing against its marketplace guidelines, which typically takes 7 to 10 business days. 3. To monitor status, open Fours → **Settings** → **Integrations**, click **Console** on the **AWS Marketplace** card. ![AWS Marketplace Console access for Professional Services](images/aws-create-and-publish-an-aws-marketplace-li-17.png) 4. Open [AWS Marketplace](https://aws.amazon.com/marketplace/management/products/saas?#), click **Professional services** from the **Build** menu, find and open your product, then check the **Requests log** tab. --- ## Listing AMI Products As an AWS Marketplace seller, you can deliver your products to buyers with Amazon Machine Images (AMIs). An AMI provides the information required to launch an Amazon Elastic Compute Cloud (Amazon EC2) instance. ### Delivery Method You can deliver AMI-based products in one of two ways: - **Single AMI** — buyers select and use the AMI as a template for an EC2 instance. Buyers find these products using the Amazon Machine Image delivery method filter. See [Creating single-AMI products](https://docs.aws.amazon.com/marketplace/latest/userguide/ami-single-ami-products.html). - **AWS CloudFormation templates** — templates that let buyers install a system of multiple instances with different roles as a single unit. Buyers find these using the CloudFormation delivery method filter. See [Delivering your AMI-based product using AWS CloudFormation](https://docs.aws.amazon.com/marketplace/latest/userguide/cloudformation.html). ### Listing Process #### 1. Build AMI - Select OS (Linux/Unix/Windows) & Architecture (64 bit Arm, 64 bit x86, 64 bit Mac, 64 bit Mac-Arm). - Disable root login. - Ensure all AMIs start with a public AMI that uses hardware virtual machine (HVM) virtualization and 64-bit architecture. - Create the AMI in the US East (N. Virginia) Region. - Use a consistent operating system (OS) user name across all versions and products. AWS recommends **ec2-user**. - For Linux-based AMIs — ensure a valid SSH port is open. The default SSH port is 22. - For Windows-based AMIs — ensure an RDP port is open. The default RDP port is 3389. The WinRM port (5985 by default) must be open to 10.0.0.0/16 and 10.2.0.0/16. - See [other AMI requirements for AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/product-and-ami-policies.html). #### 2. Scan AMI Open the [Assets - Amazon Machine Image page](https://aws.amazon.com/marketplace/management/manage-products/), set up the AWS Marketplace Ingest IAM role, and wait for the Scan status of your AMI to reach the Completed state. #### 3. Create a single-AMI product - Open the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/tour/) and sign in to your seller account. - From the Products menu, choose Server, or go directly to the [Server Products](https://aws.amazon.com/marketplace/management/products/server) page. - From the Server products tab, select Create server product, select Amazon Machine Image (AMI), and choose one of the licensing types for single-AMI products. #### 4. Review and Submit After entering the required information for all change request steps, choose Submit. This creates a request to the AWS Marketplace catalog system to validate the information and release the product to a `Limited` state if validation passes. #### 5. Test your AMI Test your product in the `Limited` state and make sure it follows AWS Marketplace [AMI-based product requirements](https://docs.aws.amazon.com/marketplace/latest/userguide/product-and-ami-policies.html) and the [product checklist](https://docs.aws.amazon.com/marketplace/latest/userguide/aws-marketplace-listing-checklist.html). Then, to publish to Public, choose Update visibility. :::note To create a private offer for an AMI product, see [AMI Private Offer](/aws-marketplace/create-private-offer#ami-private-offer). ::: --- ## Listing Container Products AWS Marketplace supports software products that use Docker containers. Container products consist of delivery options that are a set of container images and deployment templates that go together. ### Delivery Method/Option The delivery option specifies the deployment options available to the buyer. Select one of: - **Container image** — upload all the container images required for the product installation into the Amazon Elastic Container Registry (Amazon ECR) repository created in the AWS Marketplace console. - **Helm chart** — upload both the Helm chart and container images into the Amazon ECR repository created in the AWS Marketplace console. - **Amazon EKS console add-on** — upload both the Helm chart and container images into the Amazon ECR repository created in the AWS Marketplace console. ### Listing Process #### 1. Build Docker Container Requirements for building a Docker container for AWS Marketplace: - Must be configured to run with non-root privileges by default. - Must use an initial randomized password. No initial fixed or blank passwords for external administrative access. - Any outside access to the application must be explicitly agreed to and enabled by customers. - Provide detailed instructions including all steps to deploy container-based products. - Source container images must be pushed to the Amazon Elastic Container Registry (Amazon ECR) repository owned by AWS Marketplace. - Must be based on Linux. #### 2. Create Container Listing After generating the product ID, product code, and public key, use the wizard to create an initial listing: - Provide product information for your listing. - Determine the pricing model for your product. - Provide additional offer information, including a refund policy, EULA, and offer availability. - Add an initial repository for your container product. - Choose Submit on the last step to move the product to `Limited` visibility. #### 3. Add an initial version of your product Each product version has a set of container images specific to that version. To add an initial version, see [Adding a new version of your container product on AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/container-add-version.html). :::note To create a private offer for a container product, see [Container Private Offer](/aws-marketplace/create-private-offer#container-private-offer). ::: Please contact us at `support@suger.io` to get started. Our team will walk you through the tailored listing and deployment process for AMI and Container products on AWS Marketplace. --- ## Edit a Product Listing You can update existing AWS product listings directly in the Fours Console. (For non-AWS listings, a support ticket is required.) ![Editing a product listing in the Fours Console](images/aws-edit-a-product-listing-1.gif) 1. Log in to the Fours Console. 2. Click the **Products** tab. 3. Open the product listing you want to edit. 4. Click **More Actions**, then choose: - **Edit Info** — update your marketplace listing language, such as descriptions, title, and highlights. - **Edit Pricing** — update the public pricing of your listing dimensions. 5. Click **Save**. :::info After you save, Fours submits a change request to AWS, which may require automated approval. Allow 10 to 20 minutes for the updates to appear in both Fours and AWS. ::: --- ## Enable "Request a Demo" and "Request a Private Offer" Buttons AWS Marketplace lets customers request product demos and private offers directly from your listing page. A buyer fills out a form on your listing, an AWS representative discusses their needs, and the request is passed to you so you can give a demo or start a private offer discussion. This shortens the buying process and improves the customer experience by removing the need to search for your contact details. Here is how the buttons and forms appear on AWS Marketplace: ![Request a Demo and Request a private offer buttons on an AWS listing](images/aws-how-to-enable-request-a-demo-and-request-1.png) ![Request a Demo form on AWS Marketplace](images/aws-how-to-enable-request-a-demo-and-request-2.png) ![Request a private offer form on AWS Marketplace](images/aws-how-to-enable-request-a-demo-and-request-3.png) --- ## Add External Reviews (G2) You can add G2 reviews to your AWS Marketplace listing. **Prerequisites:** an existing AWS Marketplace product listing, a live G2 product profile, and access to your AWS and G2 accounts. ### Step 1: Collect the required information 1. **AWS Product Title** — in your AWS Marketplace Management Portal (AMMP), open your listed product and copy the title exactly as it appears. 2. **AWS Product ID** — in the same product view, locate the Product ID (typically starts with `prod-`). 3. **G2 Product ID** — in your G2 admin dashboard, go to product settings and find the internal Product ID (usually in the URL or metadata). 4. **G2 Profile URL** — the full URL of your public product page on G2. 5. **G2 UUID** — in your G2 admin dashboard, go to product settings and find the UUID. ### Step 2: Submit the request to AWS Send the following message to AWS Support via the AWS Marketplace Management Portal (**Support → Create Case → Marketplace**): ```plain Hi AWS Support Team, I am writing to request the addition of G2 reviews to our product listing on the AWS Marketplace. Below are the necessary details: AWS Product Title: [Insert AWS Product Title] AWS Product ID: [Insert AWS Product ID] G2 Product ID: [Insert G2 Product ID] G2 Profile URL: [Insert G2 Profile URL] G2 UUID: [Insert G2 UUID] Please let me know if you need any additional information or documentation to process this request. I appreciate your assistance in helping us integrate G2 reviews into our listing. ``` :::info - AWS may take a few business days to process the request. - Ensure all provided information is accurate to prevent delays. - You may be asked to verify ownership of your G2 profile. ::: --- ## Architecture Details As of May 1, 2025, AWS requires all products seeking to qualify for **PPA (Partner Private Offer) credit drawdown** to complete an **Architecture Review**. This review ensures your product meets AWS's technical and operational standards and is fully deployed on AWS infrastructure. If your product is **not hosted on AWS** or the architecture review has not been completed, your customers will **not** be able to use their PPA credits when purchasing your solution via AWS Marketplace. 1. Go to the [AWS Marketplace Management Portal (AMMP)](https://aws.amazon.com/marketplace/management/products). 2. Select your SaaS product. 3. Go to **Architecture Details**. ![Architecture Details tab in AMMP](images/aws-architecture-details-1.png) 4. Click **Update Architecture Details**. ![Update Architecture Details button](images/aws-architecture-details-2.png) 5. Select the correct AWS Hosting Pattern option. ![Select the AWS Hosting Pattern](images/aws-architecture-details-3.png) 6. Upload your diagram file. ![Upload your architecture diagram](images/aws-architecture-details-4.png) 7. Choose your Application plane. ![Choose your Application plane](images/aws-architecture-details-5.png) 8. Click **Update Architecture Details** to finish. ![Confirm and update architecture details](images/aws-architecture-details-6.png) See also the [AWS Architecture Guidelines](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-guidelines.html#saas-architecture). --- ## Set Product Signup URL Fours automatically syncs with AWS Marketplace and pulls all your listed product info. You can see all your products on the [Fours Console Product page](https://console.suger.io/product). Select a product, click **EDIT** in the `Product Info` section, fill in your product Signup URL in the **Fulfillment URL** field, and click `SAVE`. > Fulfillment URL field in the Product Info edit panel ## Signup URL Redirect 1. After purchasing the product, your buyer is directed to `https://api.suger.cloud/public/signup/aws/orgId/your-suger-organization-ID?partnerId=your-suger-integration-partner-ID` first. 2. Then they are redirected to your product Signup URL with two query parameters, `sugerEntitlementId` & `partner` — for example, `https://your-product-signup-url?sugerEntitlementId=1234abcd&partner=aws`. 3. Your service needs to collect this `sugerEntitlementId` and save it with the account created by the buyer. 4. More details can be found on the [how it works](/settings/signup-url-redirect#how-it-works) page. ## Marketing Insights Fours automatically syncs marketing insights from AWS Partner Central and displays them on the product detail page. ### Insights Metrics - **Buy with AWS** ([AWS Partner Central](https://us-east-1.console.aws.amazon.com/partnercentral/insights/understanding-buy-with-aws)): Monitor web traffic, engagement, and conversion metrics for your Buy with AWS experience. - **Total button clicks**: The total clicks on the call-to-action buttons on the seller website. - **Page views**: The total page visits to the Buy with AWS procurement page. - **Total agreements**: The total agreements created on the Buy with AWS procurement page. - **Sign in drop-off-rate**: AWS sign in page drop-off-rate. - **Procurement page unique visitors**: The total unique procurement page users. - **Procurement page bounce rate**: The ratio of users who create agreements to the users who just sign-in. - **Procurement page average dwell time**: The time between user sign-in and that user leaving the page in minutes. - **Customer Agreements** ([AWS Partner Central](https://us-east-1.console.aws.amazon.com/partnercentral/insights/customer-agreements)): View and analyze your product's customer agreements, including both public and private offers. - **Public Offer Agreements**: The total number of agreements from public offers. - **Private Offer Agreements**: The total number of agreements from private offers. - **New Public Offer Agreements**: The number of new agreements from public offers in the period. - **New Private Offer Agreements**: The number of new agreements from private offers in the period. - **Active Customers**: The number of currently active customers. - **New Paying Customers**: The number of new paying customers in the period. - **Listing Performance** ([AWS Partner Central](https://us-east-1.console.aws.amazon.com/partnercentral/insights/listing-performance)): Monitor and analyze your product listing's performance metrics. - **Unique Visitors**: The total number of unique visitors to the listing. - **New Public Offer Agreements**: The number of new agreements from public offers. - **New Unique Visitors**: The number of first-time visitors to the listing. - **Returning Unique Visitors**: The number of returning unique visitors to the listing. - **Seller Organic Discovery**: The number of visitors who discovered the listing organically through seller channels. - **Seller Led Marketing Campaigns**: The number of visitors from seller-led marketing campaigns. - **AWS Organic Discovery**: The number of visitors who discovered the listing organically through AWS. - **AWS Led Marketing Campaigns**: The number of visitors from AWS-led marketing campaigns. - **Search Performance** ([AWS Partner Central](https://us-east-1.console.aws.amazon.com/partnercentral/insights/search-performance)): Analyze your product's search visibility and performance in AWS Marketplace. - **Impressions**: The number of times the listing appeared in search results. - **Clicks**: The number of clicks on the listing in search results. - **Click Through Rate**: The percentage of impressions that resulted in a click. ### Preview > Marketing insights metric cards on the product page Each metric card displays two pieces of information: - **Bottom-left number**: The metric's aggregated value for the current month. - **Chart (right side)**: A series or bar chart showing the last 12 months of data. All metric data is aggregated monthly and updated daily. ### Data Availability **Why is the insight blank?** To unlock the **Buy with AWS** insight, you must have placed CTA (call to action) buttons on your website; follow the Fours doc [Buy with AWS](/aws-marketplace/buy-with-aws). To unlock the **Customer Agreements**, **Listing Performance**, and **Search Performance** insights, you must enroll in the [AWS Marketplace Seller Prime program](https://pages.awscloud.com/aws-marketplace-seller-prime.html). **Verify the data** If the data of an insight is not available, check it on AWS Partner Central. Contact us if the data is available on AWS Partner Central but not on Fours. ### Related Documents [AWS Marketplace Seller Guide: Dashboards for marketing](https://docs.aws.amazon.com/marketplace/latest/userguide/marketing-dashboards.html) [Understanding Buy with AWS as a seller](https://docs.aws.amazon.com/marketplace/latest/userguide/product-marketing.html#buy-with-aws) [AWS Marketplace Seller Prime - Intro](https://pages.awscloud.com/rs/112-TZM-766/images/AWS_Marketplace%20Seller%20Prime%20-%20Intro%20sheet.pdf) [5 things you should know about AWS Marketplace Seller Prime](https://www.fours.com/blog/aws-marketplace-seller-prime) ## FAQ ### Why do I need public pricing if I only want to sell private offers? AWS requires at least one pricing dimension above $0.00 on your public listing — dimensions can't be limited to private offers only. A common practice is to set a high placeholder price (like $100,000/year) and direct buyers to your support contact for custom pricing. When a buyer accepts your private offer, they transact at the offer price, not the public rate. ### How long does AWS approval actually take, and what causes delays? SaaS approval usually takes 2 to 4 weeks; Professional Services usually takes 7 to 10 business days. Delays can happen if required testing isn't done, descriptions don't meet AWS guidelines, or due to AWS review volume. Plan for at least 2–3 weeks and avoid tying critical deals to approval dates. ### What does `Limited` status mean, and when will my listing go public? `Limited` status is a secure testing sandbox where your listing is only visible to your account and allowlisted test accounts. **It will never go public automatically.** Once you finish testing, you must manually click **Publish Product** to send an "Update visibility" request to AWS. The listing becomes `Public` only after AWS audits and approves that request. ### Why was my product description rejected, and how do I fix it? AWS is strict about marketing language and listing metadata. Common reasons for rejection: - **Hyperbolic language** — avoid unprovable claims like "the best," "number one," or "revolutionary." Focus on factual descriptions of features and outcomes. - **Off-platform redirects** — don't include URLs or language that redirects buyers to other platforms, external payment gateways, or upsell services outside AWS Marketplace. - **Poor formatting** — avoid excessive capitalization, extra punctuation, and grammar issues. - **Unclear pricing dimensions** — each dimension must clearly explain what the customer gets, including scope or access. ### Can everything on the listing be changed at any point? How long would it take for the changes to take effect? Everything can be changed at any time except pricing, which can only be changed every 120 days and requires an AWS support ticket. ### We have two products. Can we create two listings simultaneously? Yes. ### If we remove a plan from our listing, how will it impact our existing customers? It depends on your listing type. It should not impact customers on a flat-fee contract, but customers on a subscription might be affected. In that case, open a ticket with AWS to confirm whether the dimension can be removed. ### Do we need to include the tax value in the price? No — AWS handles all the taxes. --- Source: https://doc.fours.com/aws-marketplace/submit-listing/ # Submit Your Listing for Approval Once you've completed the required implementation steps, submit your AWS Marketplace listing to AWS for final approval and go-live. --- ## Overview After your product listing is fully configured in Fours Console, the last step before your product is publicly available is submitting it to AWS for review. AWS validates your listing — including simulating the buyer experience — before switching its visibility to **Public**. Two things are needed to complete this step: 1. A completed final implementation checklist. 2. A short **Buyer Experience Demo** video that walks AWS reviewers through your product's purchase and login flow. This page covers the pre-submission checklist, how to record the demo video, and how to publish your listing. ## Final Implementation Checklist Before submitting, make sure the following items are complete: 1. **Product Listing** is complete in Fours Console. 2. **Customer Registration Page** is set up and functional. 3. **AWS Seller Profile** is registered. 4. **AWS Public Profile** is live. 5. **Tax and payment information** is completed and verified in AWS — both a **bank account** and a **disbursement method** must be added and confirmed. 6. Your **AWS account is connected** to Fours (visible under the Integrations tab). 7. Your listing is in **Limited View** mode. 8. Your **Buyer Experience Demo** video is recorded (see below). ## Buyer Experience Demo Video AWS performs a series of validations during the approval process. One of them is simulating the **buyer experience** — subscribing to the product, receiving credentials, and navigating your software. Providing a short walkthrough video lets AWS confirm this flow without requesting test credentials or scheduling calls, which accelerates your approval and go-live. :::info This video is viewed only by AWS reviewers and is **not** made public. ::: ### What to Show Record a simple walkthrough of the customer experience covering: - Navigating to your **listing on AWS Marketplace**. - Clicking **Continue to Subscribe** (or similar) to simulate a purchase. - How the buyer **receives credentials** after subscribing — if possible, include a sample confirmation email sent to the customer. - The **login screen** and logging in for the first time using the credentials from the email. - A brief walkthrough of your **product UI**, highlighting key features such as the dashboard overview, how to make integrations or connections, and how to contact support or access documentation. - Confirmation that **no payment information** is collected outside of AWS. If you don't yet have a complete platform, show how buyers will interact with the software conceptually (for example, via onboarding pages or demo tools). ### Recording Tips - Use any screen recording tool (for example, OBS or QuickTime). - Keep it short — around **2–3 minutes** — clear, and unedited. - Upload the recording to a secure platform (Google Drive, Dropbox, etc.) and make sure the link is **public or accessible without login**. - Share the link with your Fours team. Once submitted, Fours initiates the final listing approval request with AWS. ## Publish Your Listing Once the checklist items above are complete: 1. Go to your listing in the [Fours Console](https://console.suger.io). 2. Confirm it is in **Limited View** (indicated by a yellow banner). 3. Click **More Actions** and select **Publish Product**. ![Publish Product action in the Fours Console listing More Actions menu](images/aws-submit-your-aws-listing-for-approval-1.png) 4. Review your **public pricing display** under Commits and/or Usage Dimensions. If needed, update it to reflect your final intended public price. :::tip We recommend setting the price under Usage Dimensions to **$0.01** (one cent). This is a best practice for AWS Marketplace listings: once a listing is live, AWS doesn't allow changes to pricing dimensions, so a placeholder usage dimension gives you the flexibility to report or bill for additional usage later — even if you don't plan to use usage-based pricing right away — without creating a brand new listing. ::: ![Public pricing display with Usage Dimensions set to $0.01](images/aws-submit-your-aws-listing-for-approval-2.png) 5. Click **Save**. This action automatically triggers a request to AWS to update the listing's visibility to **Public**. Let your Fours Customer Success Manager (CSM) know you've completed this step. :::info If a previous change is still processing AWS Marketplace applies changes to a product one change set at a time, so publishing right after another edit can collide with it. When that happens, Fours blocks the publish before it reaches AWS and shows: > A previous change to this product is still being processed by the marketplace. Please wait a few minutes and try again. (AWS Marketplace change set: ``) Nothing was submitted. Wait a few minutes for the earlier change to finish, then click **Publish Product** again. ::: ## AWS Review Timeline AWS review time varies. It can take up to **2–4 weeks**, though many listings are approved within a few days. Once submitted, the review is entirely in AWS's hands, so please manage internal expectations accordingly. If you have questions or run into blockers during the process, reach out to your Fours Customer Success Manager for support with the final approval steps. --- Source: https://doc.fours.com/aws-marketplace/update-listing/ # Update Listing Edit, republish, restrict, or clone your existing AWS Marketplace listings from the Fours Console. --- ## Overview Once a product is listed on AWS Marketplace, you can keep it up to date from the Fours Console — updating its details, pricing, and fulfillment URL, changing its visibility, or cloning it into a new draft. What you can edit depends on the listing's current status in AWS Marketplace and your role in Fours. ### Permissions required To edit AWS listings, you need the correct permissions in both Fours and AWS. - **AWS**: Fours must be connected through an IAM role that has permissions to manage Marketplace listings. - **Fours**: **Admin** or **Editor** role. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). ### Listing status and editing permissions Your editing options depend on the listing's status in AWS Marketplace: | Status | Visibility | What you can edit in Fours | | ------------ | ------------------------ | --------------------------------------------------------------------------------------------- | | `Draft` | Private | Full access. You can edit all fields before submitting the listing. | | `Limited` | Allowlisted accounts | You can edit product information, pricing, fulfillment URL and the allowlist of AWS accounts that can see the listing for testing. | | `Public` | All AWS buyers | You can edit product information and fulfillment URL. Pricing changes are restricted by AWS rules. | | `Restricted` | Existing customers only | You can only download the listing's data spreadsheet. | ## Edit a listing's info, pricing, and fulfillment URL 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product). 2. Open the relevant AWS listing. 3. Click **More actions** in the top right corner. ![More actions menu on an AWS listing](images/aws-update-your-aws-marketplace-listings-1.png) 4. Select the action you need: - **Edit Info**: Update listing details like title, description, highlights, categories, and keywords. - **Edit Pricing**: Update contract pricing and usage dimensions (subject to AWS restrictions for live listings). - **Edit Fulfillment URL**: Update the redirect link that sends buyers to your onboarding or registration flow after subscription. 5. Make your adjustments in the dialog box and click **Save**. After saving, Fours submits a change request to AWS. Allow 10 to 20 minutes for the updates to be fully processed and appear on both platforms. For highlights and the Short Description, **Edit Info** checks AWS's limits before anything is sent. If any highlight is longer than 500 characters, Save is blocked with *"Each highlight must be 500 characters or less."* If the **Short Description** is longer than 1,000 characters, Save is blocked with *"Short Description must be 1000 characters or less."* While AWS processes a saved edit, the listing shows **Update in progress**. If AWS rejects the change, the listing moves to `Update Failed` and shows an **Update Product Failed** banner with AWS's reason. **Edit Info** stays available in that state: correct what the reason names and save again — a successful update clears the banner. Once AWS applies the edit, the listing returns to its `Public` or `Limited` status, **More actions → History** records the update, and Fours sends the **Update Product** notification (`UPDATE.PRODUCT`) — *Product … update was applied in AWS Marketplace* — to wherever you route that scope. See [Email Notification](/settings/email-notification/). :::info One change at a time AWS Marketplace applies changes to a product one change set at a time. If a previous change is still being processed, Fours stops the new one before it reaches AWS and tells you so: > A previous change to this product is still being processed by the marketplace. Please wait a few minutes and try again. (AWS Marketplace change set: ``) Nothing was submitted and nothing was lost — wait a few minutes and save again. The change set ID in the message is the in-flight change, which you can look up in the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/homepage) if you want to see what is still running. ::: :::warning If you increase the price of a live AWS listing, AWS requires a 90-day notification period for existing customers before the new price takes effect. The updated price only applies on the first day of the month after this period. Once a price increase is submitted, your pricing configuration is locked, and no further pricing changes can be made for at least 90 days. ::: ## Edits made in the AWS Marketplace Management Portal You can also edit a SaaS listing outside Fours — in the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/homepage) or through the AWS Marketplace Catalog API. Each edit reaches AWS as a change set, and AWS reports the outcome to Fours over your integration's EventBridge connection: - **AWS applies the change.** Fours refreshes the listing straight away, without waiting for the hourly sync. If that refresh fails, the hourly sync still brings the change in. - **History records it.** On the product, **More actions → History** shows *Product … was changed in AWS Marketplace* with **Source: Cloud Partner**, dated when AWS applied the change. Fours sends no email, Slack or Microsoft Teams notification for it. - **AWS rejects or cancels the change.** Nothing in Fours changes: the listing isn't refreshed and History gets no entry. The outcome still appears in the integration's **Auditing Events** as `Change Set Failed` or `Change Set Cancelled` — see [Verify](/aws-marketplace/integration/#verify). - **An edit you saved in Fours is still running.** While the listing shows **Update in progress**, Fours records the outside change in History but doesn't refresh the listing yet. The Fours update reads the listing back from AWS when it finishes. Only SaaS listings are refreshed and recorded this way. An edit you save in Fours is recorded once, by Fours' own update, not a second time as a Cloud Partner change. ```d2 shape: sequence_diagram you: "You" portal: "AWS Marketplace\nManagement Portal" aws: "AWS Marketplace" fours: "Fours" you -> portal: "Edit a SaaS listing" portal -> aws: "Submit a change set" applied: "if AWS applies it" { aws -> fours: "EventBridge: Change Set Succeeded" fours -> aws: "Read the change set and the listing" fours -> fours: "Refresh the listing and add a History entry\n(Source: Cloud Partner)" } rejected: "if AWS rejects or cancels it" { aws -> fours: "EventBridge: Change Set Failed / Cancelled" fours -> fours: "Record it in Auditing Events only" } ``` :::tip Edit a listing in one place at a time A save in Fours sends the listing as Fours holds it. If you save in Fours before an outside change has reached Fours, the older content goes back to AWS. After editing in the AWS Marketplace Management Portal, check that the change shows in Fours — or in **History** — before you edit the same listing in Fours. ::: ## Change a listing's visibility In Fours, you can update an AWS listing's visibility to control whether it's in testing, live, or restricted. ### Make a Limited listing Public 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product). 2. Open the relevant AWS listing (it displays a yellow `Limited` badge). 3. Click **More actions** in the top right corner, then **Publish Product**. ![Publish Product action on a Limited listing](images/aws-update-your-aws-marketplace-listings-2.png) 4. Review your pricing and click **Save** to submit the change request to AWS. ### Allowlist AWS accounts on a Limited listing A `Limited` listing is live on AWS Marketplace but visible only to your own AWS account and the accounts on its allowlist. Add the AWS accounts you test with — a sandbox account of your own, a partner's account, a pilot customer — so they can find the listing, subscribe, and exercise the fulfillment flow end to end before anyone else can see it. 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product). 2. Open the `Limited` AWS listing. 3. Click **More actions** in the top right corner, then **Manage Allowlisted Accounts**. 4. Enter the 12-digit AWS account IDs, one per line, and click **Save**. The list you save is the complete allowlist: accounts you leave out are removed, and an empty list removes every account you added. The change is submitted to AWS as a change request and usually applies within a few minutes; the listing shows **Update in progress** until it does, and **Update Product Failed** with AWS's message if AWS rejects an account ID. The most common rejection is an account ID that does not exist — reopen **Manage Allowlisted Accounts**, correct it and save again; a successful save clears the failure. AWS adds a few of its own operations accounts to every allowlist, so you may see accounts you did not enter. :::note A `Public` listing cannot be moved back to `Limited`. To test changes against a listing that is already public, use **Clone Product** to create a new draft — the clone enters `Limited` once created — or send a [private offer](8.create-private-offer.md) to an AWS account you control. Professional services listings have no allowlist on AWS; a `Limited` professional services listing can be extended to any buyer through a private offer. ::: ### Restrict or sunset a Public listing AWS doesn't allow listings to be deleted. Instead, you can change a listing's status to `Restricted` to stop new subscriptions while keeping existing customers active. This is done in the native AWS Marketplace Management Portal (AMMP): 1. Log in to the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/homepage). 2. Go to the **Products** tab and select your listing. 3. Click the **Request changes** dropdown, then **Update product visibility**. ![Update product visibility in AMMP](images/aws-update-your-aws-marketplace-listings-3.png) 4. Select **Restricted**. 5. (Optional) Add a **Replacement product ID**. Use this field if you're replacing this listing with a new one. AWS will notify existing subscribers and guide them to the new listing. ![Restricted visibility with replacement product ID](images/aws-update-your-aws-marketplace-listings-4.png) 6. Click **Submit** to start the takedown process. ## Clone an AWS listing The **Clone Product** feature lets you duplicate an existing AWS listing in Fours. This creates a new draft pre-filled with your existing setup, so you can reuse the details and update only what's needed. ### Step 1: Clone the listing in Fours 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product). 2. Open the relevant AWS listing. 3. Click **More actions** in the top right corner, then **Clone Product**. ![Clone Product action on an AWS listing](images/aws-update-your-aws-marketplace-listings-5.png) 4. **Edit** the newly created draft to update its specific details (such as the Product ID or pricing) and save your changes. ### Step 2: Finalize and submit the new listing Once cloned, the new listing appears in your catalog as a `Draft`. You can now modify it and submit it to AWS. 1. Open the cloned draft in Fours. 2. Update unique fields like pricing or Product ID. 3. Click **Create** or **Save** to submit the listing directly to AWS for approval. ### Step 3: Test and publish the listing Once AWS processes your cloned draft, it appears in your Fours Console with a `Limited` status. Since the clone is treated as a new AWS listing, you'll need to complete the standard go-live steps before it can be used by new buyers. See [Create and publish an AWS Marketplace listing](/aws-marketplace/list-product/) for the full test and publishing process. ## FAQ ### Why can't I change my pricing immediately after updating it? AWS has a 90–120 day restriction on pricing changes for marketplace listings. Once you update pricing, you must wait this period before making another pricing change. ### Should I make changes in Fours or directly in the AWS Marketplace console? For most listing changes, use the Fours Console, as it syncs with AWS. However, for Professional Services listings, you must make changes directly in the AWS Marketplace Management Portal — these can't be edited through Fours. If you do edit a SaaS listing in the portal, Fours picks up the change once AWS applies it and records it in History — see [Edits made in the AWS Marketplace Management Portal](#edits-made-in-the-aws-marketplace-management-portal). ### How long do listing changes take to appear publicly? Most changes require AWS approval and can take anywhere from a few hours to several days, depending on the type of change. ### My changes aren't saving or syncing properly. What should I do? First check the listing's detail page. If it shows an **Update Product Failed** banner, AWS rejected the change — the banner quotes AWS's reason, so correct it with **Edit Info** and save again. If there is no banner, the change may simply still be processing (**Update in progress**) or waiting on a sync between Fours and AWS: refresh your browser and check whether the changes appear. If they still don't, contact Fours support. ### What parts of my listing can I edit, and what's locked? You can typically edit descriptions, pricing (subject to the 90-day rule), images, and most metadata. However, some core product attributes and Professional Services listings have restrictions. The Fours interface shows you which fields are editable for your specific listing type. --- Source: https://doc.fours.com/aws-marketplace/create-private-offer/ # Create Private Offer An AWS Marketplace private offer is a set of negotiated terms — which can include a custom pricing plan, an end user license agreement (EULA) or a custom solution — that you extend to specific buyer AWS accounts. Only those accounts can see it, and an offer the buyer accepts becomes an agreement. You can create and manage all of your AWS Marketplace private offers from the Fours Console or the Fours API. --- ## Overview You can create several types of private offer in AWS Marketplace. The table below lists them and the features each one supports. | | Description | Expiry Date | End Date | Commit(s) | Usage Dimensions | Payment Installments | Multiple Currency | | :------------------------------ | :-------------------------------------------------------------------------- | :----------------: | :---------------------------: | :----------------: | :----------------: | :------------------: | :---------------------------------: | | **Subscription Offer** | Private offer for Subscription product (pay as you go, usage-based) | :white_check_mark: | :white_check_mark: | - | :white_check_mark: | - | - | | **Contract Offer** | Private offer for Contract product (commit only) | :white_check_mark: | - | :white_check_mark: | - | :white_check_mark: | :white_check_mark: | | **Combined Offer** | Private offer for Contract-Subscription Combined product | :white_check_mark: | - | :white_check_mark: | :white_check_mark: | :white_check_mark: | - | | **Agreement Based Offer** | Private offer based on existing active agreement for manual renew or upsell | :white_check_mark: | - | :white_check_mark: | :white_check_mark: | :white_check_mark: | Available for contract based offers | | **Professional Services Offer** | Private offer for Professional Services product | :white_check_mark: | | :white_check_mark: | | :white_check_mark: | :white_check_mark: | | **Container Offer** | Private offer for Container product | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | **AMI Offer** | Private offer for AMI product | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | **Free Trial Offer** | Public Offer for free trial | - | by the end of Free Trial term | - | - | - | - | :::danger - You may create private offers either on the **Offers** page in [AWS Partner Central](https://us-east-1.console.aws.amazon.com/partnercentral/home) or in the [Fours Console](https://console.suger.io/offer). ::: ## Prerequisites Before you proceed, make sure both your AWS and Fours environments are ready. This prevents errors during offer creation and approval. - **AWS requirements** — make sure your AWS account is set up with the following: - **Active AWS Marketplace listing** — you must already have at least one public AWS Marketplace product (SaaS, AMI, Container, or Professional Services). Private offers must be created from an existing listing. - **Registered AWS Marketplace Seller account** — your AWS account must be enrolled as a Marketplace Seller in the AWS Marketplace Management Portal (AMMP). - **Completed company profile** — your business details in AWS Marketplace must be fully filled out. - **Tax and banking setup completed** — your tax information and banking details must be added and verified in AWS Marketplace. - **Required IAM permissions** — your AWS user or role must have permissions to create and manage Private Offers. - **Fours requirements** — you need an **Admin** or **Editor** role. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). - **Buyer requirement** — you must collect the buyer's **AWS Account ID (12-digit)**. This is required to target the private offer correctly. ## Quick Start: Create a Private Offer This is the end-to-end workflow for creating any private offer in the Fours Console. The specific fields you fill in depend on your product's pricing model — see the per-type sections below for details. ![Create a new private offer in the Fours Console](images/aws-creating-a-private-offer-in-the-suger-co-1.gif) ### Step 1: Create the draft offer 1. Go to the **Offer** menu in the [Fours Console](https://console.suger.io/offer). 2. Click **+ New Private Offer**, then choose the **AWS product** you want to associate with the offer. Only products already connected to your AWS Marketplace account appear here. Each product shows its type and, when it belongs to a specific AWS account, that account's ID (for example `SAAS · `). Search by the ID to tell same-named products in different accounts apart. ![Create a new private offer and select a product](images/aws-create-an-aws-marketplace-private-offer-1.webp) ### Step 2: Fill in basic information This section defines who the offer is for and how it's tracked. 1. Enter the **Offer Name** — this custom name is displayed to the buyer. 2. Optionally link a **Salesforce** or **HubSpot** deal. 3. Select the **Buyer AWS Account(s)**. 4. **Add or create contacts** — internal or customer-facing people who should be notified. 5. (Optional) Add a **Description (Internal)** — notes for your team only, never shown to the buyer, of up to 1,000 characters. Fours measures that limit in bytes, so accented and non-Latin characters count as two or more each. :::info Characters allowed in the name and description AWS Marketplace accepts only standard ASCII plus a short list of symbols — `¢`, `£`, `¤`, `¥`, `©`, `®`, and `™` — in an offer's **name** and **description**. Anything else (accented letters, curly quotes, em dashes, emoji, CJK characters) is replaced with a space before the offer is sent, and runs of whitespace are collapsed. If your buyer's legal entity name contains such characters, expect the submitted name to differ from what you typed — use a plain-ASCII transliteration so the buyer sees what you intend. ::: ### Step 3: Fill in the offer terms This section defines how long the offer is valid and how long the contract runs after acceptance. 1. Set the **Expiry Date** — the deadline for the buyer to accept the offer. 2. Specify the **Contract Term Length** — the duration of the contract after acceptance. 3. (Optional) **Enable future start date** — used when the contract should begin on a fixed start date, any time after acceptance. 4. (Optional) Choose a **Buyer net payment term** — see below. ### Buyer net payment term Every AWS buyer already has net payment terms agreed with AWS at the account level. A private offer can override them for this deal alone. The field has two modes: | Mode | What Fours sends to AWS | When to use it | | --- | --- | --- | | **Customer's net terms with AWS** (default) | Nothing — the offer carries no payment-term change at all, and the buyer keeps whatever terms their AWS account already has. | Almost always. Leave this alone unless you have explicitly agreed something different with the buyer. | | **Custom** | The term you pick, one of the six below. | Only after the buyer has agreed to it in writing. | The six custom terms are: | Option | Buyer pays within | | --- | --- | | Net 15 days | 15 days of the invoice | | Net 30 days | 30 days | | Net 45 days | 45 days | | Net 60 days | 60 days | | Net 90 days | 90 days | | Net 120 days | 120 days | Before you set one, four things are worth knowing: - **It applies to pay-by-invoice buyers only.** AWS may charge a credit-card buyer immediately regardless of the term on the offer. - **A longer term delays your disbursement.** AWS pays you after the buyer pays AWS, so Net 120 pushes your money out by roughly four months compared with Net 30. - **It cannot be changed after release.** Once the offer leaves `Draft` the term is fixed. To change it, create a new offer. Fours blocks the edit before it reaches AWS, and AWS itself rejects it with *"Net payment terms cannot be changed after release; create a new offer or resale authorization."* - **Not every product is eligible.** The control is disabled, with the reason shown in the form, when the product is not an AWS Marketplace product, when its status is `Restricted`, `Pending`, or `Draft`, when Fours has not yet synced a matching AWS listing for the product type, or when the product belongs to a reseller — in which case you set the ceiling on the [resale authorization](/aws-marketplace/cppo/#maximum-buyer-net-payment-term) instead. The field is available on every AWS private-offer form Fours builds — SaaS, contract, professional services, container, AMI, machine learning, and agreement-based offers — and the chosen term is shown read-only on the resulting offer and entitlement. If your team works from offer configuration templates, the same value is exposed there as **AWS Invoice Payment Term**: the negotiated buyer payment term on a private offer, or the maximum buyer payment term on a resale authorization. If AWS refuses the term, Fours surfaces the reason rather than the raw error code: | What AWS refused | Message you see | | --- | --- | | The term is not one AWS accepts | Choose Net 15, 30, 45, 60, 90, or 120. | | The product is not eligible | Use an eligible private AWS Marketplace offer. | | The seller account is not enabled for resale net payment terms | This seller account or integration is not enabled for resale net payment terms; omit the maximum or resolve eligibility with AWS. | | The term exceeds the resale authorization's maximum | Use the authorization maximum or a shorter term; an authorization without a maximum cannot add one. | | The offer is already released | Net payment terms cannot be changed after release; create a new offer or resale authorization. | | Anything else | AWS could not apply net payment terms; review eligibility or create a new offer. | ### Step 4: Fill in pricing information Depending on your AWS product type, your private offer uses different pricing mechanics: - **Subscription (usage-based)** — the customer pays based on actual usage. Set usage dimensions (what is being measured) and the unit price per dimension. - **Contract (fixed commitment)** — the customer pre-pays or commits to a fixed spend. Set the total commit amount, currency, and optional payment installments. - **Combined (contract + usage)** — a fixed baseline plus extra usage billing. Set the commit amount (base contract) and usage pricing (overage charges). - **Reseller / CPPO (markup-based)** — you're not setting a base price, you're adding margin. Set a markup percentage or a custom payment structure. See the per-type sections below for the full field breakdown of each pricing model. #### Discounting dimensions off list price When you price by discount rather than by absolute rate, the dimension-discount panel writes each dimension's net rate as *list price × (1 − discount)*. Two things are worth knowing: - **Prices are rounded to AWS's 8-decimal submit precision.** Fours quantizes the resulting rate to the same precision AWS effectuates, so the savings shown in the console are the savings the buyer actually gets. Without it, a very small discount could survive on screen but be rounded away by AWS at submit time, and a very deep one could round to $0. - **Each section has a reset control.** The circular-arrow button on a discount section clears that section back to list price — it zeroes the section's discount percentage *and* drops the per-dimension overrides underneath it. This matters on a cloned offer, where the carried-over prices are stored as overrides that changing the header percentage alone cannot clear. ![The dimension-discount panel — the Percent / Absolute toggle and the running Base · Net · Save totals across the top, a tag-filtered discount section at 25% whose per-section reset (circular arrow) is enabled, and an Uncategorized section still at list price whose reset is greyed out. Each row shows the dimension, its tags, the list unit rate, and the net rate at AWS's 8-decimal precision](images/71-dimension-discount-panel.png) ### Step 5: Add legal terms Select the agreement the buyer accepts: - Standard Contract for AWS Marketplace, or - a custom EULA. A custom EULA needs its file: upload it before you submit, because the offer cannot be created without it. ### Step 6: Finalize and submit 1. Review the offer and make sure everything is correct. 2. Click **Create offer**. Fields marked with an asterisk (*) are required, and which ones depends on your choices — **Start date**, for example, only once you enable a future start date. **Create offer** stays greyed out while a required field is empty or a value isn't valid. To see what's left, hover over the button, or press Tab until it has focus: its tooltip, headed *Please complete:*, lists each step that still needs work and the fields in it — for example, *Step 2 Offer terms — Expiry Date* — with the reason beside any value that isn't valid. A value that isn't valid is also outlined in red, with the reason beneath the field. :::tip - You can use a generic SKU to avoid reaching AWS's SKU limit. For example, set the **Dimension Name** to `YourCompanyName Private Offer` and the **Description** to `Access to YourCompanyName Platform`. ::: ## Subscription Private Offer To create a private offer for a subscription product, the ISV seller is allowed to customize the unit prices of the dimensions for usage metering. The private offer has both expiry date & end date. Click the button of `Create Offer` in the [Fours console offer page](https://console.suger.io/offer), select the target AWS Subscription SaaS product and fulfill the info listed as below: - **Custom Offer Name**: Custom name for your offer will be displayed to the buyer. - **Buyer(s)**: one or multiple buyer's AWS Account IDs who will receive the private offer and are capable to accept it. - **Expiry Date**: The date before when the private offer needs to be accepted, otherwise, the offer expires. - **End Date**: The date when the private offer subscription will end. This value must be greater than the upper offer expiry date. :::warning - Only for Subscription Private Offer: the price switches back to the public offer after the end date arrives. ::: - **Usage Dimension Absolute Price**: Configure the absolute price of each usage metering dimensions. An example is shown below: > Usage dimension absolute price configuration example - **End User License Agreement**: Select the EULA between Standard AWS Marketplace Contract, Enterprise AWS Marketplace Contract or your custom contract. ## Contract Private Offer To create a private offer for a contract product, the ISV seller is allowed to customize the commit amount. The private offer has both expiry date & contract term length. By default, the contract starts when the buyer accepts the offer. If a future start date is specified, the contract will commence from the designated time. Fulfill the info listed as below: - **Custom Offer Name**: Custom name for your offer will be displayed to the buyer. - **Buyer(s)**: one or multiple buyer's AWS Account IDs who will receive the private offer and are capable to accept it. - **Expiry Date**: The date before when the private offer needs to be accepted, otherwise, the offer expires. - **Start Date(optional)**: A future date when the contract will begin if the offer has been accepted. - **Currency**: Choose a transaction currency for this offer. You will receive payment in the selected currency. :::warning - Before select non-USD currency, make sure you have configured your [non-USD disbursement preferences for multi currency](#multi-currency). ::: - **Term Length**: In months. How long the buyer can use the contract commits sold in this offer. - **Commit Amount**: How much the buyer need to pay for this contract private offer. - **End User License Agreement**: Select the EULA between Standard AWS Marketplace Contract, Enterprise AWS Marketplace Contract or your custom contract. :::info Up to 200 commit dimensions per offer An offer can carry at most **200** commit dimensions, matching AWS Marketplace's own pricing-dimension quota. A contract offer must have at least one. Beyond 200, the offer is rejected with `the offer has more than 200 commits, which is not allowed` — consolidate onto a generic SKU (see the tip in [Step 6](#step-6-finalize-and-submit)) rather than listing every line item as its own dimension. ::: ## Contract + Subscription Combined Private Offer The private offer for Contract + Subscription Combined product is similar to the combination of previous two types of private offer. You can customize both the commit amount and usage metering dimension prices for extra usage. Fulfill the info listed as below: - **Custom Offer Name**: Custom name for your offer will be displayed to the buyer. - **Buyer(s)**: one or multiple buyer's AWS Account IDs who will receive the private offer and are capable to accept it. - **Expiry Date**: The date before when the private offer needs to be accepted, otherwise, the offer expires. - **Term Length**: In months. How long the buyer can use the contract commits sold in this offer. - **Commit Amount**: How much the buyer need to pay for this contract private offer. - **Usage Dimension Absolute Price**: Configure the absolute price of each usage metering dimensions. - **End User License Agreement**: Select the EULA between Standard AWS Marketplace Contract, Enterprise AWS Marketplace Contract or your custom contract. ## Private Offer with Payment Installments By enabling the payment installments, you can extend private offers with a custom payment schedule. The schedule can be spread over up to five years, and the customer makes payments in regular installments. After they are subscribed, your customers can see all the payments on the schedule and on their AWS invoice, helping them track their spending. > Custom payment installment schedule for a private offer :::warning - `Payment Installments` are only supported in [Contract Private Offer](#contract-private-offer), [Contract + Subscription Combined Private Offer](#contract--subscription-combined-private-offer), or [Agreement Based Private Offer](#agreement-based-private-offer). - Common mistakes when configuring Payment Installments: 1. Multiple invoices on or before the offer expiration date **(only one is allowed)**. 2. The client/buyer's AWS Account is **not on net payment terms** with AWS, which is required to accept Payment Installments. ::: ## Agreement Based Private Offer When you have an active entitlement of the [Contract](/aws-marketplace/pricing-model/#contract-upfront-commitment) or [Combined](/aws-marketplace/pricing-model/#contract-with-subscription-combined) product with your buyer, you can manually renew or upsell the entitlement by creating an agreement-based private offer. Once the new private offer is accepted by the buyer, the entitlement will be updated immediately. :::warning - Only the entitlements of Contract or Combined products / private offers allows to create the agreement-based private offer. The subscription does not allow the agreement-based private offer, which means that no flexibility to manually renew or upsell in Subscription pricing model. ::: The list of info required when creating the agreement-based private offer: - **Custom Offer Name**: Custom name for your offer will be displayed to the buyer. - **Expiry Date**: The date before when the private offer needs to be accepted, otherwise, the offer expires. - **New End Date**: The date when the new private offer will end. - **Currency**: The currency of the new agreement based offer will firstly inherite from the base agreement, then if it is not a usage based offer, you can change it to one of these supported currencies. - **Commit Quantity**: The number of the commit plan, mostly it is 1. - **Usage Dimension Absolute Price**: Configure the new absolute price of each usage metering dimensions. - **Payment Scheduler**: You can specify one or multiple dates to bill the buyer with specified amount. The total amount of payment installments is the final commit amount of the new private offer. One example is shown below: > Payment scheduler example for an agreement-based private offer - **End User License Agreement**: Choose **Use existing EULA**, **Append to Existing EULA**, **Use your own EULA**, or **Standard Contract for AWS Marketplace**. **Append to Existing EULA** and **Use your own EULA** both need an uploaded file: until you upload it, the section stays incomplete and the offer cannot be created. ## Professional Services Private Offer To create a private offer for a professional services product, the ISV seller can customize the commit price and payment installments. The private offer includes both an expiry date and a contract term length. The offer becomes active when the buyer accepts it. Fulfill the info listed as below: - **Custom Offer Name**: Custom name for your offer will be displayed to the buyer. - **Buyer(s)**: one or multiple buyer's AWS Account IDs who will receive the private offer and are capable to accept it. - **Expiry Date**: The date before when the private offer needs to be accepted, otherwise, the offer expires. - **Term Length**: In months. How long the buyer can use the contract commits sold in this offer. - **Currency**: Choose a transaction currency for this offer. You will receive payment in the selected currency. :::warning - Before select non-USD currency, make sure you have configured your [non-USD disbursement preferences for multi currency](#multi-currency). ::: - **Commit Price**: How much the buyer need to pay for each commit. > Commit price configuration for a professional services private offer :::warning - You can specify multiple commits in the private offer, but the buyer can only select one of them to purchase. ::: - **Payment Scheduler**: You can specify one or multiple dates to bill the buyer with specified amount. The total amount of payment installments is the final commit amount of the new private offer. One example is shown below: > Payment scheduler example for a professional services private offer - **End User License Agreement**: Select or upload your custom contract. ## Container Private Offer To create a private offer for a container product, you can choose pricing model depends on the product's pricing model and it's dimension types. :::tip - AWS supports free private offers for container products with Free pricing or only RecurringPayMonthly pricing. BYOL container products are still not supported. - Hourly pricing products behave very similarly to Usage metering pricing products when creating private offers. The difference is that the former only have one dimension called Hours. ::: :::warning No start date on Container or AMI offers AWS does not accept a start date for **Container** or **AMI** private offers. If one is set, Fours removes it before submitting and records a warning on the offer — only the **agreement duration** is sent, and the contract begins when the buyer accepts. Plan these offers by duration, not by a fixed start date; if you need a future start, use a product type that supports one. ::: | Product Pricing Model | Product Dimension Type | Offer Pricing Model | Expire Date | Contract Duration | Usage End Date | Commit(s) | Payment Installments | Usage Dimensions | Multiple Currency | | -------------------------------------- | ---------------------- | -------------------------------------- | ------------------ | ------------------ | ------------------ | ------------------ | -------------------- | ------------------ | ------------------ | | Contract pricing | Entitled | Contract pricing with installment plan | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | | :white_check_mark: | | Contract pricing | Entitled | Contract pricing with upfront payment | :white_check_mark: | :white_check_mark: | | :white_check_mark: | | | :white_check_mark: | | Usage metering pricing, Hourly pricing | ExternallyMetered | Contract pricing with installment plan | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | :white_check_mark: | | | Usage metering pricing, Hourly pricing | ExternallyMetered | Contract pricing with upfront payment | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: | | | Usage metering pricing, Hourly pricing | ExternallyMetered | Usage pricing | :white_check_mark: | | :white_check_mark: | | | :white_check_mark: | | ## AMI Private Offer To create a private offer for a AMI product with pricing model of Hourly pricing or Free, you can choose a target pricing model for the offer. :::warning - Currently AWS does not support creating private offers for AMI products with pricing model BYOL. - You will find that the form of creating a private offer for AMI Product is basically the same as the Container Product with Usage metering pricing model. ::: | Product Pricing Model | Product Dimension Type | Offer Pricing Model | Expire Date | Contract Duration | Usage End Date | Commit(s) | Payment Installments | Usage Dimensions | Multiple Currency | | --------------------- | ---------------------- | -------------------------------------- | ------------------ | ------------------ | ------------------ | ------------------ | -------------------- | ------------------ | ----------------- | | Hourly pricing, Free | Metered | Contract pricing with installment plan | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | :white_check_mark: | | | Hourly pricing, Free | Metered | Contract pricing with upfront payment | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: | | | Hourly pricing, Free | Metered | Usage pricing | :white_check_mark: | | :white_check_mark: | | | :white_check_mark: | | ## Free Trial Public Offer Visit the [AWS Marketplace Free Trial Offer console](https://aws.amazon.com/marketplace/management/offers?tabId=publicFreeTrials), and click the button `Create free trial offer`. Select the product and enter the amount of days as the Free Trial term length. The offer may take ~1 hour before being effective & public visible. :::danger - During the Free Trial term, the buyers won't be charged on the commit or usage metering. ::: :::danger - The Free Trial entitlement will be terminated/cancelled automatically by the end of Free Trial term. ::: ## Resale Private Offer As a Reseller on AWS, you can create the resale private offer based on a ResaleAuthorization which you received from other ISV/Sellers. Click the button of `New Private Offer` in the [Fours console offer page](https://console.suger.io/offer), enable `As Reseller` to fill in the details to finalize the private resale offer. - **Custom Offer Name**: Custom name for your offer will be displayed to the buyer. - **Buyer(s)**: One or multiple buyer's AWS Account IDs who will receive the private offer and are capable to accept it. - **Expiry Date**: The date before when the private offer needs to be accepted, otherwise, the offer expires. - **End Date**: The date when the private offer subscription will end. This value must be greater than the upper offer expiry date. - **Markup Options**: The markup will be applied to the wholesale pricing to generate the contract pricing, including the customer price and partner margin. For contract private reseller offer with predefined installments, you can choose between `Markup Percentage` and `Custom Payments` to set the markup, and for other private offers, the only available option is `Markup Percentage`, so this field will be hidden. > Markup options for a resale private offer - **Markup Percentage**: By providing a percentage, the contract pricing (including customer price and partner margin) will be calculated based on the wholesale pricing. If the offer has predefined installments, every installment amount will be updated automatically based on the markup percentage. > Markup percentage field for a resale private offer - **Custom Payments**: Instead of providing a percentage, you can set the custom payments for each installment. The sum of all installments will be the contract price. The implicit markup percentage will be calculated based on the custom payments and the wholesale pricing, usage dimensions prices will be updated automatically based on the implicit markup percentage. > Custom payments configuration for a resale private offer - **End User License Agreement** (optional): Turn on **Add Custom EULA** to attach your own contract. Once it is on, the file is required — the section shows *"Please upload a EULA file when using 'Use your own EULA' option."* and the offer cannot be created until you upload it. ## Contract Private Reseller Offer To create a private reseller offer for a contract product (or contract + subscription combined), there are two pricing models to choose from `Contract pricing with installment plan` and `Contract pricing with upfront payment`, it is similar to creating normal contract private offers. > Contract private reseller offer creation form The private reseller offer has both expiry date & contract term length. By default, the contract starts when the buyer accepts the offer. If a future start date is specified, the contract will commence from the designated time. Fulfill the info listed as below: - **Custom Offer Name**: Custom name for your offer will be displayed to the buyer. - **Buyer(s)**: one or multiple buyer's AWS Account IDs who will receive the private offer and are capable to accept it. - **Expiry Date**: The date before when the private offer needs to be accepted, otherwise, the offer expires. - **Start Date(optional)**: A future date when the contract will begin if the offer has been accepted. It should be noted that for pricing model `Contract pricing with upfront payment`, you must set the start date. - **Contract Duration**: The duration options comes from the ResaleAuthorization which current offer based on. - **End User License Agreement**: Select the EULA between Standard AWS Marketplace Contract, Enterprise AWS Marketplace Contract or your custom contract. ### Contract pricing with upfront payment #### Set markup percentage It is the default pricing model for contract private reseller offer. After setting the start date and contract duration, you need to set the markup percentage, it will affect partner margin and customer price of all commits. If usage dimensions exist in this offer, they will be affected too. Start date must be set in this pricing model. > Set markup percentage for contract pricing with upfront payment ### Contract pricing with installment plan #### Select contract duration and set commit quantity If you select pricing with installment plan, it means you have to specify the quantity for each commit to get the contract amount. Different contract duration has different commit unit price. In this pricing model, commit unit price can not be configured. > Select contract duration and set commit quantity #### Setup markup You can set the markup by specifying the total contract price or setting a percentage. When setting the markup, you can see the latest value of the partner margin. > Set markup by total contract price or percentage > Partner margin value after setting markup #### Add payment installment Then you need to add installment according to the contract total amount and contraction duration. Using the `Payment Scheduler` tool will make it easy. > Add payment installment using the Payment Scheduler tool > Payment installment schedule for contract duration #### Review usage dimensions Usage dimensions' price will be updated automatically according to the previous markup settings. > Usage dimension prices updated by markup settings ## Multi Currency Sellers can now create private offers in EUR, GBP, JPY, and AUD for all pricing types (including contract, usage-based, and contract with consumption) and receive their disbursements in the offer currency. Additionally, sellers are no longer required to have a US-domiciled bank account. Instead, they can choose to receive payments into one or more bank accounts located in [any seller eligible jurisdiction](https://docs.aws.amazon.com/marketplace/latest/userguide/user-guide-for-sellers.html#eligible-jurisdictions). For channel partner private offers (CPPO), the seller, channel partner, and buyer must all transact in the same currency. Sellers need to issue a resale authorization in the negotiated currency, and the channel partner then creates the CPPO in that currency. :::info - **Enter the amount in the offer's currency — don't pre-convert it yourself.** AWS displays a USD-equivalent alongside your entered amount for reference only. ::: **How currency affects FX risk:** - If you denominate the offer in a specific currency (for example, GBP), the buyer sees, accepts, and gets invoiced in that currency at a fixed rate locked at acceptance — no FX risk for the buyer over the contract term. - If you keep the offer in USD but the buyer pays in another currency, the exchange rate is variable and recalculated at each invoice date (not locked for the term). For multi-year deals where the buyer wants FX certainty, denominate the offer directly in their currency instead. - If you're setting up non-USD disbursement for the first time, make sure your AWS seller account has a SWIFT-enabled disbursement method and keeps USD on file. KYC verification for non-USD payouts can take several days — plan ahead if the offer's expiry date is close. - For CPPO / reseller offers specifically: the seller, channel partner, and buyer must all transact in the same currency. Confirm the resale authorization's currency before setting pricing. :::tip - Make sure you have configured your non-USD disbursement preferences. To enable a specific currency, follow this [guide](https://docs.aws.amazon.com/marketplace/latest/userguide/disbursement.html) to set your bank disbursement methods in [AWS Marketplace Management Portal Settings](https://aws.amazon.com/marketplace/management/seller-settings/account). - Multi-currency support is available for all private offer pricing types, including contract-only, usage-based, contract with consumption, Professional Services, and CPPO offers. - `USD` is the only default currency to create all public offers. ::: This functionality is available worldwide for all AWS Marketplace sellers for all private offer pricing types, including usage-based and contract with consumption pricing. Public offers remain in USD only. To get started, sellers need to provide bank accounts with SWIFT codes and associate currency preferences. To learn more, please visit the documentation on [local currency offers and disbursements](https://external-aws-mp-isvs.s3.amazonaws.com/Internationalization/Local_Currency_Cheatsheet_Seller.pdf). ## Share the Offer and Track Its Status Once you click **Create**, the offer is sent to AWS and prepared for the buyer. You can track its status from the **Offers** page in the Fours Console. ### Status flow in the Console 1. Immediately after creation, the offer appears in the list with the status `Pending_Create`. 2. Wait up to **5 minutes**, then refresh the page. The status updates to one of the following: - `Create_Success` — the offer was successfully created in AWS Marketplace but has **not yet been sent** to the buyer. - `Pending Acceptance` — the offer has been **pushed to AWS** and the buyer has been notified. 3. When the buyer accepts the offer, the status changes to `Accepted`. An **Offer** object and **Entitlement** record are also generated within Fours to reflect the successful transaction. 4. Click on the offer in the list to open its full detail page, where you'll find all offer information, status history, pricing breakdown, and entitlement tracking. #### If the offer does not get created Two statuses mean nothing exists in AWS Marketplace, and both are recoverable without starting over: - `Create_Failed` — the offer reached AWS and AWS refused it. - `Invalid` — the offer was rejected before it ever left Fours, because its own shape or target could not be accepted. Either way, the reason is written onto the offer's detail page, and the offer keeps its **Edit** and **Submit** actions: fix what the message names, then resubmit the same offer. If you would rather abandon it, both statuses are also eligible to be **archived**, alongside `Draft`, `Expired`, and `Cancelled`. #### If AWS rejects a change to a live offer A change that AWS refuses on an offer that already exists — for example, extending its expiry date — leaves the offer in `Update_Failed`, and its detail page shows an **Update Offer Failed** alert quoting AWS's reason. Closing the alert hides that one failure only: if a later change is rejected too, the alert returns with the new reason. #### See every rejected attempt For a create or a change that AWS rejected, open the offer and choose **More actions → History**. In the **Offer History** drawer, the failed entry carries a **Why AWS rejected this** panel: AWS's error code and message, how many times Fours sent the request, and the most recent attempts (up to three) with their times and change set IDs. The **Logs** tab on the Offers page shows the same panel for each failed run, with the full **Raw error** behind a disclosure. #### See who made each change **Offer History** entries show where each change came from on a **Source** line and, when a person made it, who on a **By** line. When you submit, cancel or extend an offer from the console, the entries Fours writes while it carries that out — from **Pending Create** through **Pending Acceptance** for a new offer — name you, with **Source: User**. Entries nobody on your team triggered, such as a scheduled sync or the offer expiring, show **Source: Fours backend** and no **By** line. Older entries may be missing one or both lines. :::tip - Entitlements created after offer acceptance are also visible under the **Entitlements** section in the Fours Console, giving you full visibility into access provisioning. ::: ### Send the offer link to the buyer 1. Open the created offer. 2. Click **Actions**, then **Copy offer URL**. 3. Share the URL directly with the buyer so they can log into their AWS account, review the terms, and accept the offer. ## FAQ ### What is the correct AWS Account ID format and how do I collect it from buyers? The AWS Account ID must be exactly 12 digits (no dashes or spaces). This is different from other AWS identifiers. You can find it in the AWS Console under "My Account", or ask your buyer to provide it from their AWS billing dashboard. Make sure you're not confusing it with other AWS IDs like IAM user IDs or resource ARNs. ### Why doesn't my offer status match between Fours and AWS, and when will I get acceptance notifications? Status sync delays can occur due to AWS API timing or integration issues. Offers typically sync within 15–30 minutes, but can take longer during high-traffic periods. For acceptance notifications, ensure your notification settings are properly configured in Fours settings. If you see discrepancies (for example, `Pending` in Fours but `Expired` in AWS), wait for the next sync cycle or contact support to manually refresh the status. ### Can I create an AWS private offer in a currency other than USD? Yes. Private offers support USD, EUR, GBP, AUD, and JPY (INR is India-only). Enter the amount in your chosen currency — AWS shows a USD-equivalent for reference, but don't convert it yourself. For CPPO/reseller offers, the seller, channel partner, and buyer must all use the same currency. ### How do we find out when a private offer gets accepted? Once the offer is accepted, you will be notified via email. Additionally, the offer status on Fours will be updated to Accepted. ### How do I cancel a private offer? A button called 'cancel offer' is on the offer details page inside the console. ### How does payment for a private offer work? For a flat commit, the customer will be invoiced based on the payment scheduled. If no payment is scheduled, they will be invoiced on acceptance day or a few days after. Then, the disbursement will happen based on their payment terms with the cloud provider. The cloud provider will typically disburse those funds a few days following the disbursement to AWS. ### I created an offer with the wrong EULA. Can it be updated? Once an offer is created, it cannot be updated. So, the route here is to cancel it and recreate it again. You can clone it and attach the correct EULA to the new one. ### We have a customer who purchased our product and is now looking to add another group of users (an expansion to the current offer). What is the best way to do this? It depends on whether the product has [Concurrent Agreements](/aws-marketplace/integration/#enable-concurrent-agreements). With Concurrent Agreements, send the expansion as a new private offer: the buyer accepts it as a second agreement, and the existing agreement continues unchanged. Without it, a buyer can hold only one active agreement per product in an AWS account, so create an Agreement-Based Offer (ABO), which we call an Upsell/Renewal Offer in Fours. When the buyer accepts it, it replaces their current agreement. ### We are doing a renewal. If the offer has expired, do we have to make an Agreement-Based offer or a New offer? In this case, you make a regular private offer. ### We need to extend the expiry of our private offer by two weeks, but it's failing. What should I do? Extending this offer will not work in this case because you have a payment installment date set before this two-week extension. You'll need to create a new offer with a first installment date to set as the expiration date. ### I tried creating an offer via AWS on Fours and got this error: 'Failed to create offer: Offer PaymentTerms.Schedule.ChargeOn is not valid'. You probably set your offer charge date to a past date; it must be in the future. ### We have a customer who provided the wrong AWS account number, and we need to update the offer. Assuming we cannot change the AWS account number on an offer, what is the best way to update the offer? You can clone the existing offer, update the AWS account number, push the new offer to the customer, and then cancel the previous one. ### We didn't find any acceptance confirmation in AWS Marketplace and didn't get any email notifications. Could you please check that the Private Offer was correctly accepted and help us set up proper email notifications? Whenever you see an Entitlement associated with an Offer, it means that it has been accepted. We can funnel notifications into your Slack channel for internal purposes. For external people (end buyers), you can add contacts when you first create the offer, OR you can add notification contacts after the offer has been created. Those contacts receive the offer-ready and offer-accepted emails only when **Enable Email Notification** is on for your organization and the `PENDING_ACCEPTANCE.OFFER` and `ACCEPT.OFFER` rows are enabled with the **Offer Notification Contacts** rule — see [Email Notification](/settings/email-notification/). ### We have a rip-and-replace AWS offer sent to a customer who has an existing offer with us through AWS, but they cannot accept it due to this message "You already have a contract for this product". That message means the product does not have [Concurrent Agreements](/aws-marketplace/integration/#enable-concurrent-agreements) enabled, so the buyer can hold only one active agreement for it. To process an upsell or renewal for that customer, do it from the existing agreement/entitlement. To do this, you can go to the specific entitlement, click the upsell/renew button, and enter the upsell details. This will allow the customer to accept the new agreement, given the change in terms. Please note that if an installment has already been paid, the upsell will be net of the amount already paid; the second installment will be the total amount for the second year of the upsell. ### When a customer accepts an offer, we alert the customer and our Account Executive. Is someone from AWS also notified? They'll only get visibility of it when you Launch the Opportunity and link that Opportunity to the Offer during the Launch process. ### Can we set a future start date for a renewal offer the same as for initial private offers, or will the effective start date always be the acceptance date? It depends on how you renew. An agreement-based offer — **Upsell / Renew** on the buyer's entitlement — always starts when the buyer accepts it, and you control only its new end date: AWS does not allow a future start date on an amended agreement. To have a renewal start after the current contract ends, create a new contract private offer with **Enable future start date** turned on. The buyer can accept it while the current contract is still running, as long as auto-renewal on the current agreement is turned off first. ### What is the lifecycle of an entitlement? The customer cannot cancel, so when we receive "Pending cancel" and "Cancel" event notifications? What happens at the end of the term if there's no auto-renewal? When a private offer is accepted, it automatically generates an entitlement/agreement. The customer has control over that agreement to either continue subscribed or unsubscribe. If they unsubscribe to your product, you will receive a notification from AWS within hours that the agreement was canceled. (You will receive both PENDING CANCEL and CANCEL webhook events from Fours. The time gap between these two events usually be 1 hour) As for no auto-renewal, the contract will expire after the contract end date, and you'll receive a notification from AWS stating that the agreement was canceled. If you wish to renew with this customer, you must create a new Private Offer. ### Our customer has an active offer with an end date of June 14th. If I set the new offer with a June 15th start date, can they accept it early in June 5th without any issue? Yes, they can accept the offer on June 5th, as long as the start date is AFTER the end of the ongoing contract and auto-renewal on the ongoing contract is turned off before they accept. AWS doesn't let a buyer accept a future-dated offer while auto-renewal is on, and it can't be turned back on afterwards. ### Does AWS Marketplace have Auto-renew available for offers? Yes, in two different forms. On a **public** SaaS listing, the buyer chooses auto-renewal at purchase and can switch it later; the seller does not control that choice. On a **private offer**, the seller can attach **pre-authorized renewal terms** — the renewal option, a fixed or ranged price uplift, an optional renewal decision deadline, an adjustment deadline and a renewal count — which the buyer accepts along with the offer. After acceptance the seller can still adjust the uplift inside the agreed range, or opt out of the renewal, until the relevant deadline passes. See [Pre-Authorized Auto-Renewal](/aws-marketplace/pre-authorized-auto-renewal/). ### When we generate a Private Offer link for our customers, who else (besides the customer and our Account Executive) gets notified? Does someone on the AWS side get notified, too? They don't get notified. Only the contacts you add to the offer are emailed, and only when **Enable Email Notification** is on for your organization and the `PENDING_ACCEPTANCE.OFFER` and `ACCEPT.OFFER` rows are enabled with the **Offer Notification Contacts** rule — see [Email Notification](/settings/email-notification/). During the creation process, you could add your success manager, PDM, or any other AWS Rep as a contact for those Offers. ### Why does the point of Contact (POC) not automatically appear as a contact on private offers when the deal is a renewal? The offer in the renewal deal is created from entitlement instead of opportunity, so the contacts are not auto-populated from the opportunity owner. ### Does the opportunity owner (the Account Executive or Account Manager) get an email when the offer is accepted? or do they get the email letting them know the offer is ready? Yes, if they are contacts on the offer: offer contacts get both the offer-ready and the offer-accepted email, provided **Enable Email Notification** is on for your organization and the `PENDING_ACCEPTANCE.OFFER` and `ACCEPT.OFFER` rows are enabled with the **Offer Notification Contacts** rule. See [Email Notification](/settings/email-notification/). --- Source: https://doc.fours.com/aws-marketplace/offer-best-practices/ # Private Offer Best Practices Follow these best practices to create and manage AWS Marketplace private offers through the Fours Console and the Fours Salesforce App so your offers are accurate, timely, and aligned with AWS Marketplace requirements. --- ## Overview Private offers let you sell to a specific buyer at negotiated terms. Before you create one, keep these general considerations in mind: - **Eligibility** — Only SaaS, Professional Services, AMI, and Container products with public listings can be used to create private offers. - **Offer visibility** — Private offers are not visible in the public AWS Marketplace; only the targeted buyer sees them. - **Start and end dates** — Offers can be future-dated. AWS only triggers entitlement events on the offer start date, which may delay sync visibility. - **Acceptance timeline** — Buyers typically have 90 days to accept a private offer. As the seller, you set the expiry (acceptance) date when creating the offer. For step-by-step instructions on each offer type, see [Create Private Offer](/aws-marketplace/create-private-offer/). ## Required Information Before you create a private offer in Fours, collect or define the following: - **Buyer ID (AWS Account ID)** — Always request the 12-digit AWS Account ID directly from the buyer. - **Start and end dates** — Be clear with the buyer about when the offer becomes active. - **Pricing details** — Confirm all pricing terms before submission, including upfront fees, recurring charges, and usage dimensions (if applicable). ## Best Practices for Creating Private Offers 1. **Double-check the Buyer ID.** Mistyped Buyer IDs cause offer failures. Copy-paste directly from a confirmed source. 2. **Use clear offer naming.** A standardized naming convention helps your team track offers easily. 3. **Add notification contacts.** Always include your internal contact and the buyer's email for visibility and acceptance tracking. 4. **Use the comments field.** Include internal notes or specific buyer context for internal visibility. 5. **Create from your CRM.** If you have a CRM integration, create most offers from a CRM Opportunity or Deal. This gives sellers in your company visibility into acceptance status, dates, expiration, and more. ## Field Reference and Best Practices Use this table as a reference for each field when creating a private offer. | Field | Description | Best practices | | --- | --- | --- | | **Offer Name** | The name of the offer that is visible to the buyer. | Use a clear, consistent format such as `CustomerName - ProductName - MM/YYYY`. | | **Buyer(s)** | AWS Account ID(s) of the customer. Supports multiple IDs. | Always request the 12-digit AWS Account ID directly from the buyer and verify accuracy to avoid offer failures. | | **Contact(s)** | Internal and customer contacts notified when the offer is sent. | Include the customer's name and email. Optionally add your internal email to receive a copy of the notification. | | **Expiry Date** | Date by which the buyer must accept the offer before it expires. | Align with your internal deal timeline and communicate the deadline clearly to the buyer. | | **Start Date** | When the offer becomes active. Defaults to the buyer's acceptance date unless a future date is set. | Only visible if you enable **Future Start Date**. If enabled, it must be after the offer's expiry date — for example, if the expiry date is **June 30, 2025**, the future start date must be **July 1, 2025** or later. | | **End Date** | When the offer ends. Used to calculate term length and enforce usage cutoffs. | Only visible if you enable **Future Start Date**. Typically set to 1 year after the start date unless contract terms specify otherwise. | | **Commit Term Length** | Duration during which commits can be used by the buyer. | Disabled if you enable **Future Start Date** (replaced by the Start Date and End Date fields). Make sure it matches the expected usage or contract period (e.g., 12 months). | | **Payment Installments** | Splits payment into multiple scheduled installments. | Ensure payment dates are in the future and match your billing plan — AWS doesn't allow back-dated installments, and installments must be listed in chronological order. Even for one-time, upfront payments, enable **Payment Installments** with a single installment. This is especially important when the offer includes multiple SKUs, as it ensures consistent processing and clearer tracking across all line items. | | **Commits (SKUs)** | Defines the services and amounts the customer is purchasing. | Add the relevant SKU(s), set the quantity, and confirm all pricing before submitting. Define a **generic SKU** you can reuse across most deals — suggested format is Dimension Name `{{Your Company Name}} Private Offer` and Description `Access to {{Your Company Name}} Platform`. This helps avoid reaching the AWS limit of 72 SKUs; once hit, you can't create additional SKUs without removing or consolidating existing ones. | | **Usage Dimensions & Unit Price** | Pricing for metered usage (optional). | Set appropriate prices if using usage-based billing. | | **EULA** | End User License Agreement attached to the offer. | Use AWS's default EULA or upload your own. If uploading, ensure it's a signed PDF, and optionally merge it with the default contract. | | **Renewal** | Indicates whether the offer renews an existing subscription. | Toggle **Migration Renewal** for non-Marketplace to Marketplace conversions. Use **Direct Renewal** if renewing a prior AWS Marketplace deal. | | **Description (Internal)** | Notes visible only to your internal team. Not shown to the buyer. Up to 1,000 characters, measured in bytes — accented and non-Latin characters count as two or more. | Use to track context, approvals, or internal comments to help with team collaboration. | ## After Offer Creation - Use the Fours Console or your CRM to track the status of the private offer. Share the offer link with teammates who need to follow it. - Expect a delay in sync updates for offers with a future start date. While Fours automatically tracks acceptances using triggering events from AWS, AWS does not report the acceptance of a future-dated private offer until the offer's actual start date. On that day, Fours retrieves the acceptance status through scheduled syncs, which may take up to 3 hours. Offers without a future start date typically trigger an immediate update upon acceptance. ## Private Offer Lifecycle 1. **Offer creation.** A private offer is created in the Fours Console or via the Salesforce App, with all required details including buyer ID, pricing, and terms. 2. **Offer sent to buyer.** The offer is automatically pushed to AWS Marketplace and made available to the buyer for review and acceptance. 3. **Buyer accepts offer.** The buyer logs in to their AWS Marketplace account and accepts the private offer. 4. **Fours syncs acceptance status.** Upon acceptance, AWS triggers an event or exposes the accepted status (depending on the start date). Fours captures this update and notifies the seller. 5. **Entitlement created in Fours.** Fours creates a new **Entitlement** record in both the Fours Console and your CRM, confirming the buyer now has access under the accepted offer. :::info If no entitlement is created, review the entitlement canceled reasons for potential issues. ::: :::tip Renewals restart the cycle When AWS auto-renews an agreement, the renewal term gets its own new entitlement and the previous one is cancelled — it is not an extension of the original record. Build your CRM and reporting rules around the buyer or the agreement rather than the entitlement row. See [Auto-renewal creates a new entitlement](/aws-marketplace/accept-private-offer/#auto-renewal-creates-a-new-entitlement-for-sellers). ::: ![Private Offer Life Cycle diagram: a private offer is created, sent for acceptance, and accepted by the buyer; Suger receives the acceptance confirmation from AWS, sends it to the seller, and creates the entitlement record in Suger Console and the CRM](images/aws-private-offer-best-practices-1.png) For channel partner (reseller) deals, see [CPPO](/aws-marketplace/cppo/) for the equivalent best practices and lifecycle. --- Source: https://doc.fours.com/aws-marketplace/cppo/ # Channel Partner Private Offers (CPPO) Authorize a reseller to transact your software on AWS Marketplace on your behalf, and create and manage Channel Partner Private Offers (CPPO) and Resale Authorizations in Fours. --- ## Overview The `Channel Partner Private Offer` (CPPO) empowers Independent Software Vendors (ISVs) to grant Channel Partners access to wholesale pricing for their software solutions. This functionality enables ISVs to delegate the financial and contractual aspects of customer relationships within the AWS Marketplace to their Channel Partners. Within the Fours platform, ISVs/Sellers can efficiently oversee `CPPO resell opportunities`, `CPPO private offers`, and `CPPO entitlements` in a unified manner. Additionally, `CPPO entitlements` benefit from overage usage metering support when the relevant usage metering dimensions are available. ### Key terms - **Channel Partner Private Offer (CPPO)** — A private offer where a channel partner works with an ISV to sell a product to a buyer through the marketplace. - **Resale Authorization** — A configuration in Fours that allows a Channel Partner to resell a product. It defines pricing, terms, and allowed plans. - **ISV (Independent Software Vendor)** — The company that owns and publishes the software in AWS Marketplace. - **Channel Partner (Reseller)** — The partner who sells the ISV's product to the buyer and creates the final private offer. Each cloud marketplace has its own term for this reseller motion — on AWS it's the **Channel Partner Private Offer (CPPO)**, on Azure it's the **Multiparty Private Offer (MPO)**, and on GCP it's the **Reseller Private Offer (RPOP)**. In Fours, all three are managed the same way under **Resale Authorizations**. This page covers the AWS flow; for the other clouds, see [Azure Resale Authorizations](/azure-marketplace/cppo/) and [GCP Resale Authorizations](/gcp-marketplace/cppo/). ## Requirements ### AmazonEventBridgeFullAccess The AWS managed IAM policy `AmazonEventBridgeFullAccess` is required, to set up the notification webhook for the CPPO related events, such as `CPPO_OUT` offer released, or `CPPO` offer created by the reseller. Please attach the `AmazonEventBridgeFullAccess` IAM policy to the IAM role created by the Fours CloudFormation stack when connecting the AWS Marketplace integration. ### Service-linked role for AWS Marketplace It is required to enable the CPPO function in the Fours platform. AWS Marketplace uses the service-linked role named `AWSServiceRoleForMarketplaceResaleAuthorization`, which enables access to AWS services and resources used or managed by AWS Marketplace for Resale Authorizations. Both parties (ISV and Channel Partner) must enable this role so that AWS can process and exchange resale authorizations between accounts. Here are the steps to set up the service-linked role: 1. In the [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/homepage?pageType=awsmpmp%3Acustomer), sign in to the management account and choose Settings. 2. In the Settings section, select the Service-linked roles tab. 3. On the Service-linked roles page, select Service-linked role for Resale Authorizations or Resale Authorizations integration, and then choose Create service-linked role or Configure integration. 4. On the Service-linked role for Resale Authorizations or Create Resale Authorizations integrations page, review the information and confirm by choosing Create service-linked role or Create integration. A message appears on the Service-linked roles page, indicating that the Resale Authorization service-linked role was successfully created. ### Product and account eligibility - **Register as AWS Marketplace sellers.** Both the ISV and the Channel Partner must be registered AWS Marketplace sellers. - **Publish an eligible product (ISV only).** The ISV must have an active, publicly listed product in AWS Marketplace (SaaS, AMI, Container, or Professional Services). Only published products can be used in CPPO deals. - **Fours admin access.** You need **Admin** access to the Fours Console to create a Resale Authorization. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). :::info - CPPOs are **not** visible in the public AWS Marketplace — only the targeted reseller will see them. ::: ## Required information When creating a Resale Authorization, collect or define the following before you proceed: - **Reseller ID (AWS Account ID):** Always request this directly from the reseller. - **Buyer ID (AWS Account ID):** Optional. Always request this directly from the buyer. - **Start and End Dates:** Communicate to the reseller the period during which the authorization will be available to use. - **Pricing Details:** Align on the discount type you will provide to your reseller. - **EULA:** This document will be visible to the end buyer. - **Reseller agreement:** This document will be visible only to the reseller. ## Create a Resale Authorization The Fours Console lets you create a Resale Authorization (`CPPO_OUT`) directly, independently of a CRM. From the [Fours Console](https://console.suger.io/resale/sent) main menu, click **Resale** in the left-hand navigation, then follow the steps below. ![How to create a reseller authorization in Fours](images/aws-how-to-create-a-reseller-authorization-i-1.gif) ### Step 1: Create the resale authorization 1. **Open the Resale Authorization flow.** 1. Go to the **Resale** page in the [Fours Console](https://console.suger.io/resale/sent). 2. Click **+ New Resale Authorization** in the upper-right corner. 3. Select the **AWS Product** you want to use. This defines what the Channel Partner is allowed to resell. Only products already connected to your AWS Marketplace account appear here. 2. **Add basic information.** - **Opportunity Name** — a name to identify the resale authorization (visible to the reseller). - (Optional) **Salesforce Opportunity** — link the record to a Salesforce Opportunity. - (Optional) **HubSpot Deal** — link the record to a HubSpot Deal. - (Optional) **Description** — describe the purpose of the authorization. - **Reseller Account** — the partner allowed to resell. - (Optional) **Buyer(s)** — restrict the authorization to specific end customers. - (Optional) **Contact(s)** — associate contacts with the authorization. - (Optional) **Description (Internal)** — internal notes. 3. Set **Contract Duration** to define how long the resale authorization is valid (in months). 4. **Set pricing information.** - **Currency** — the pricing currency used in the authorization. - **Discount Type** — how pricing is applied (see the field reference below). - **Commits** — the committed spend terms. - **Usage Dimensions** — usage-based pricing items, if applicable. 5. **Set availability.** - **Selling Authorization Availability** — how the authorization can be used: - **Single Use** — the partner can use this authorization once to create a single private offer. - **Specific time duration** — the partner can create multiple offers until the expiry date. - **No set time duration** — the partner can create unlimited offers until you manually deactivate the authorization. - **Expiry Date** — the date after which the authorization can no longer be used. - **Maximum allowed service start date** — the latest possible service start date. - (Optional) **Maximum buyer net payment term** — see [below](#maximum-buyer-net-payment-term). 6. **Add other information.** - **EULA** — the legal terms shown to the end buyer. - **Reseller Agreement** — the reseller-side legal terms. - **Renewal** — whether this authorization is a renewal offer. 7. Click **Create offer**. It stays greyed out while a required field — marked with an asterisk (*) — is empty or a value isn't valid; hover over it, or press Tab until it has focus, to see what's left. :::tip You can save the offer as a draft and finish creating it later. ::: The status shows `Pending Create` while AWS processes it. After a few minutes, refresh the page to see it change to `Active`, meaning it has been sent to the Channel Partner, who can then add markup and issue the final private offer. ### Step 2: Hand off to the Channel Partner Once your resale authorization becomes `Active`, the Channel Partner takes ownership of creating the final private offer. As the ISV, you can't build the offer for them, but you must initiate the handoff and monitor the deal's progress. 1. **Notify the Channel Partner.** 1. Open the active authorization in the Fours Console. 2. Click **More actions** in the top-right corner, and select **Notify Contact**. This sends the reseller an email with a direct link to the authorization, letting them know it's ready to use. 2. **Coordinate deal details.** Work with your partner to confirm the correct buyer AWS Account ID and align on timing for when the final offer will be sent to the buyer. ### Step 3: Track buyer acceptance and entitlements After the reseller generates the private offer, you won't see their final markup, but you can oversee the entire deal lifecycle in the Fours Console. - **Track your wholesale plan (`CPPO_OUT`).** Once the reseller generates the private offer, your original Resale Authorization status changes to `Used`. If you allowed multiple uses, it stays `Active` so the reseller can use it again. - **Monitor the new private offer (`CPPO`).** A new deal entry appears automatically with the type `CPPO` and a `Pending Acceptance` status, confirming the final private offer has been delivered to the buyer and is awaiting approval. - **Confirm buyer acceptance.** Once the buyer accepts and the offer is activated, a **CPPO Entitlement** is generated automatically. This is your authoritative record of the active contract and supports overage usage metering if applicable. :::warning If the private offer includes a **future start date**, expect a delay in sync updates. AWS does not report the acceptance of a future-dated private offer until the agreement's actual start date. On that date, Fours retrieves the acceptance status through scheduled syncs, which may take up to 3 hours. Offers without a future start date typically trigger an immediate update upon acceptance. ::: ## Field reference and best practices When creating a Resale Authorization via Fours, use the table below as a reference for each field. | Field | Description | Best practices | | --- | --- | --- | | **Opportunity Name** | The name of the offer that will be visible to the reseller. Required, **1–100 characters** after leading and trailing spaces are trimmed. The characters `;`, `"`, `'`, `<`, and `>` are not allowed; spaces and ordinary punctuation such as `_`, `-`, `/`, `.`, `(`, and `)` are fine. | Use a clear, consistent naming format such as `ResellerName_ProductName_MM/YYYY`. Avoid apostrophes in company names — write `Acme Corps Renewal`, not `Acme Corp's Renewal`. | | **Description** | Selling authorization description. Optional. | A short description of what the resale authorization covers, what was agreed with the reseller, or other relevant notes. | | **Reseller Account** | AWS Account ID(s) of the reseller. | Always request the 12-digit AWS Account ID directly from the reseller and verify accuracy to avoid offer failures. If you don't find the reseller name in the dropdown list, contact [support@suger.io](mailto:support@suger.io). | | **Renewal** | Indicates if the offer renews an existing subscription. | Toggle "Migration Renewal" for non-Marketplace to Marketplace conversions. Use "Direct Renewal" if renewing a prior AWS Marketplace deal. | | **Buyer(s)** | AWS Account ID(s) of the end buyer. Supports multiple IDs. Required for a renewal opportunity. | To restrict the authorization to a specific end buyer, request the 12-digit AWS Account ID and verify accuracy. If the authorization can be used with any buyer, leave the field empty. Don't list the reseller's own account here: Fours refuses an authorization whose **Buyer(s)** include the **Reseller Account** ID (*the reseller cannot be its own buyer*). Remove that ID from **Buyer(s)** — or, if the wrong partner was chosen, correct **Reseller Account**. | | **Commit Term Length** | Duration during which the buyer can use the commits. | Disabled when creating a CPPO for a Subscription product. Ensure this matches the expected usage or contract period (e.g., 12 months). | | **Discount Type** | How you'd like to apply discounts to the public price. | **Flexible payment schedule** (most popular): define payment installments, choosing the amount and invoice date. **Individual pricing**: apply specific discounts to a commit. **Percentage discount**: apply a single discount rate to all selected products. | | **Payment Installments** | Splits payment into multiple scheduled installments. | Disabled if you select "individual pricing" or "percentage discount". Ensure payment dates are in the future and match your billing plan — AWS doesn't allow back-dated installments, and installments must be in chronological order. Even for one-time, upfront payments, enabling Payment Installments with a single installment ensures consistent processing across multiple SKUs. In **JPY**, every installment amount must be a whole number — the form stops you with *JPY amounts must be whole numbers. Remove the decimals from each installment amount.* No installment can fall after the **Contract Duration**, counted from the day you submit; Fours refuses it with *…is after the end of the N-month contract term…* — lengthen the duration or move the date. AMI products are exempt from that check. | | **Percentage Discount** | The discount percentage compared to the public price. | Disabled if you select "individual pricing" or "flexible payment schedule". | | **Commits (SKUs)** | The services and amounts the customer is purchasing. | Add the relevant SKU(s), set the quantity, and confirm all pricing before submitting. Define a **generic SKU** that can be reused across most deals to avoid reaching the AWS limit of 24 SKUs for CPPO. Suggested format — Dimension Name: `{{Your Company Name}} Private Offer`; Description: `Access to {{Your Company Name}} Platform`. | | **Usage Dimensions & Unit Price** | Pricing for metered usage (optional). | Set appropriate prices if using usage-based billing. | | **Duration** | How long the license is available for the reseller to use. | **Single use**: one offer per product specified (the only option if you select "flexible payment schedule"). **Specific time duration**: expires after the specified expiry date. **No set time duration**: lasts until you manually deactivate it. | | **Expiry Date** | The date by which the reseller must use the authorization. | Align this with your reseller and communicate the deadline clearly with the buyer. | | **Maximum buyer net payment term** | The longest net payment term the channel partner may give the end buyer. Optional. | Leave it unset unless you have agreed a term with the partner — see [Maximum buyer net payment term](#maximum-buyer-net-payment-term). It cannot be changed once the authorization is released. | | **EULA** | The EULA visible to the buyer. Applied to all selling authorizations created. | Use AWS's default EULA or upload your own. If uploading, ensure it's a signed PDF; you can optionally merge it with the default contract. | | **Reseller Agreement** | The reseller agreement between you and the channel partner. Not visible to the buyer. | Upload the signed agreement with the terms agreed upon. | :::tip - **Double-check account IDs.** Mistyped Reseller and Buyer IDs cause offer failures — copy-paste directly from a confirmed source. - **Use clear offer naming.** A standardized naming convention helps your team track offers easily. - **Use the description field.** Include notes or specific buyer context for your reseller's visibility. - **Track after creation.** Use the Fours Console or your CRM to track the CPPO status, and share the offer link with teammates who need to follow it. ::: ## Maximum buyer net payment term A resale authorization can cap how generous the channel partner may be about when the end buyer pays. Set **Maximum buyer net payment term** on the authorization and the partner can offer that term or a shorter one — never a longer one. The ceiling is one of the same six options a direct private offer uses: Net 15, 30, 45, 60, 90, or 120 days. Leave it unset and the authorization does not authorize custom net payment terms at all. How it plays out downstream, when the partner builds the buyer-facing offer in Fours: | On the authorization | On the partner's offer | | --- | --- | | No maximum set | The partner cannot set a buyer net payment term. Attempting one is refused: *the linked resale authorization does not authorize custom net payment terms*. | | A maximum is set, partner picks nothing | The offer inherits the maximum as its buyer term. | | A maximum is set, partner picks a shorter term | The shorter term is used. | | A maximum is set, partner picks a longer term | Refused: *the buyer net payment term cannot exceed the resale authorization maximum*. | Two constraints carry over from direct offers. Like any released payment term it is **immutable** — once the authorization leaves `Draft` the ceiling is fixed, and changing it means creating a new authorization. And your seller account has to be enabled for it: if AWS is not, the authorization is rejected with *"This seller account or integration is not enabled for resale net payment terms; omit the maximum or resolve eligibility with AWS."* See [Buyer net payment term](/aws-marketplace/create-private-offer/#buyer-net-payment-term) for what the term means for the buyer and for your own disbursement timing. ## CPPO lifecycle The end-to-end flow of a CPPO deal in Fours: 1. **Offer creation (`CPPO_OUT`).** You create a Resale Authorization in the Fours Console or via the Salesforce App, with all required details including buyer ID, pricing, and terms. 2. **Offer sent to reseller.** The offer is automatically pushed to AWS Marketplace and made available to the reseller for review and acceptance. 3. **Reseller accepts offer.** The reseller logs in to their AWS Marketplace account and accepts the Resale Authorization. 4. **Fours syncs acceptance status.** Upon acceptance, AWS triggers an event or exposes the `Active` status (depending on the start date). 5. **Reseller uses the authorization.** When used, the status becomes `Used` (for single-use or specific-time-duration authorizations; otherwise it stays `Active`). An offer of type `CPPO` appears with status `Pending Acceptance` — this is the private offer your reseller sent to the end buyer. 6. **Buyer accepts the private offer.** The buyer logs in to their AWS Marketplace account and accepts the private offer. 7. **Entitlement created in Fours.** Fours creates a new **Entitlement** record in both the Fours Console and your CRM, confirming the buyer now has access under the accepted offer. ## Track CPPO status in the Fours Console After submitting a Resale Authorization, track its status from the **Offers** page in the Fours Console. **Offer types** - `CPPO_OUT` — the Resale Authorization you send out to the reseller. - `CPPO` — the private offer the reseller sends to the end buyer. - `CPPO_IN` — a Resale Authorization you received as a reseller. **Status flow** - **`Pending Create`** — immediately after creation. Wait up to **5 minutes**, then refresh the page. - **`Active`** — the authorization was successfully created in AWS Marketplace and shared with the reseller. - **`Create Failed`** — an error occurred during creation. Open the offer to view the error message, fix it via **Edit Draft**, and create the offer again. - **`Used`** — the reseller has used the authorization. - **`Expired`** — the reseller didn't use the authorization before the expiry date. You'll need to create a new authorization. - **`Restricted`** — you manually deactivated the authorization. :::tip Use the **Clone Offer** feature to resubmit an expired CPPO — it creates a copy of the offer where you can edit the fields and submit again. ::: Click any offer in the list to open its full detail page, where you'll find all offer information, status history, pricing breakdown, and entitlement tracking. ### Refresh the authorizations you received If you also *resell* another ISV's product, the **Received** tab of the **Resale** page has a **Sync received resale authorizations** button in its toolbar. Click it to pull your `CPPO_IN` authorizations from AWS Marketplace on demand instead of waiting for the next scheduled sync — useful right after an ISV tells you they have sent one. Fours confirms with `Sync triggered. Received offers will be updated in a few minutes.` The sync runs in the background, so refresh the list after a few minutes to see the result. The button appears only when your organization has **Enable Reseller** turned on. If you don't see it and you expect to receive authorizations, ask Fours support to enable reselling for your organization. ![The Resale list on the Received tab — the search box, Cloud Partner and Status filters and Filters popover on the left, with the "Sync received resale authorizations" button in the toolbar above the table of authorizations other sellers have granted you](images/70-resale-received-sync.png) ## Cancel a Resale Authorization Cancelling a resale authorization lets you manually stop a Channel Partner from using an active authorization before its expiration date. Once deactivated, the authorization is no longer usable for creating new private offers. :::warning Cancellation is not retroactive: - Existing private offers remain active and valid. - Only future use of the authorization is blocked. ::: To cancel an authorization: 1. Go to the **Resale** tab in the Fours Console. 2. Find and click the **name** of the authorization you want to deactivate. 3. Select **Cancel** in the upper-right corner. 4. Confirm the action when prompted. The status initially changes to `Pending_Cancel` while AWS processes the request, and permanently updates to `Canceled` (or `Restricted`) once confirmed. ## Clone a Resale Authorization Use the **Clone** feature when you need to change an existing resale authorization. This is the main way to update terms like pricing, expiry dates, or EULA, since active authorizations can't be edited. :::tip If you're cloning to replace an active authorization, make sure to cancel the original one. This prevents partners from accidentally using outdated terms. ::: To clone an authorization: 1. Go to the **Resale** (or **Offers**) tab in your Fours Console. 2. Open the authorization you want to update. 3. Click **More actions** in the top-right corner. 4. Select **Clone**. 5. Review the new draft and update required fields (pricing, expiry date, EULA, etc.). 6. Click **Create** to submit the new authorization to AWS. Once the status is `Active`, inform your Channel Partner to use the new version. :::note What cannot be cloned Clone applies to the authorizations **you** create (`CPPO_OUT`). Two related objects have no Clone action, by design: - **`CPPO_IN`** — a resale authorization you *received* from another vendor. It is a read-only copy of their object, synchronized from the marketplace; there is nothing of yours to copy. - **`CPPO`** — the final buyer-facing offer, which is owned by the channel partner rather than by you. If you are a reseller and need different terms, ask the ISV to issue a new authorization. ::: ## CPPO Resell Opportunity You, as ISV/Seller, can authorize channel partners to resell your products by creating a `CPPO resell opportunity` for these partners in the Fours platform. Click **New Resale Authorization** on the [Fours Console offer page](https://console.suger.io/offer), select the target AWS SaaS product, and fill in the info listed below: - **Opportunity Name**: Custom name for your opportunity, displayed to the reseller. - **Reseller Account**: Reseller account attached to this opportunity. - **Buyer(s)**: To constrain resale to specific buyers, add the buyer AWS account ID. Required if it is a Renewal Opportunity. - **Commit Amount**: How much the buyer needs to pay for the contract private offer created by this opportunity. - **Usage Dimension Absolute Price**: Configure the absolute price of each usage metering dimension. An example is shown below: > Usage Dimension Absolute Price configuration example - **Expiry Date**: The opportunity is valid until the expiry date. - **End User License Agreement**: Select the EULA between the Standard AWS Marketplace Contract and your custom contract. - **Flexible Payment Installments (optional)**: Specifies payment installment details, applicable only to **Contract** offers. :::danger - `CPPO resell opportunities` are stored in the Fours platform as Offers with type = `CPPO_OUT`. ::: ## CPPO Private Offer After the `CPPO resell opportunities` have been created, authorized channel partners can offer one or more of the products on AWS Marketplace. They will extend `CPPO private offers` to the end buyers based on these resell opportunities. Fours promptly receives notifications as soon as these `CPPO private offers` are generated. :::danger - `CPPO private offers` are stored in the Fours platform as Offers with type = `CPPO`. ::: ## CPPO Entitlement After the end buyer accepts the `CPPO private offer` initiated by the channel partner, Fours automatically generates an active entitlement for the transaction. The `CPPO Resell Opportunity`, `CPPO Private Offer`, and `CPPO Entitlement` are interconnected, providing ISVs/Sellers with a comprehensive overview of the entire CPPO deal process. :::danger - `CPPO entitlements` are stored in the Fours platform as Entitlements with type = `CPPO`. ::: ## FAQ ### How do we know when a CPPO is accepted? Is there a notification in Fours? Once the entitlement is about to start, AWS will send you a confirmation that the customer has signed the contract, and you'll also receive a confirmation on the Fours console of a new Offer. ### We have a CPPO offer that was accepted in March. The reseller has asked us to add 30 licenses. Is there a way in Fours to send out another CPPO offer that will override the current offer and start a new agreement immediately? In this case, only the reseller can create an agreement-based offer to add the 30 additional users. Ideally, a situation like this should only be managed through metering. Customers who accept an offer with an additional usage option agree to pay future overages, which is why it's the ideal solution. There's no way to replace an existing CPPO offer. In the case of a CPPO, the agreement exists between the customer and your reseller. --- Source: https://doc.fours.com/aws-marketplace/dimension-sync/ # Sync Dimensions to Private Offers Add newly-listed usage dimensions to your already-released AWS private offers in bulk, by uploading a reviewed worklist. --- ## Overview When you add a new usage metering dimension to a product's public listing, the private offers that were **already released** keep the dimension set they had when they were created. Buyers on those offers cannot be metered on the new dimension until it is added to their offer. This tool lets you add one or more missing dimensions to a batch of released private offers at a price you specify — in a single upload — **without changing any existing dimension or price** on those offers. :::tip - The price you enter is the standalone rate for the dimension (typically the public **list price**). It is applied as-is; it is **not** a discount or a markup. - **Nothing is applied automatically.** Dimensions are added only for the offers and prices listed in the worklist you upload. ::: ```d2 direction: down template: "1 · Download template\nOffers → Settings → Products →\nDimension Sync to Private Offers" worklist: "2 · Fill the worklist\nOfferId, ProductId,\nMissingDimension, Price" upload: "3 · Upload\n.xlsx or .csv\nup to 60,000 rows · 20 MiB" rejected: "Rejected — no offer touched\nrequired header missing" running: "4 · Running\nprocessed / total offers" completed: "Completed\napplied · skipped · failed, by offer" cancelled: "Cancelled\nalready-submitted offers still finish" failed: "Failed\nprocessed offers are still reported" report: "5 · Report\none row per (offer, dimension):\napplied / skipped / failed + reason" template -> worklist -> upload upload -> rejected: "missing required header" { style.stroke-dash: 4 } upload -> running: "Accepted — applying\nin the background" running -> completed: "all offers processed" running -> cancelled: "you click Cancel" running -> failed: "task could not complete" completed -> report cancelled -> report failed -> report ``` ![Settings → Private Offer → Dimension Sync to Private Offers — the Upload worklist button above the task list, each row showing its status, creation time and per-row result counts](images/dimension-sync-worklist.png) ## Before you start - Your organization is an AWS Marketplace seller (has a connected AWS integration). If you don't see the card described below, contact Fours to enable this feature for your account. - You are signed in to the [Fours Console](https://console.suger.io) as an **admin** of the organization. - You know the target private offer IDs and the dimension keys you want to add. ## Where to find it In the Fours Console, open **Offers**, then the **Settings** tab → **Products** → the **Dimension Sync to Private Offers** card. ## Step 1 — Download the worklist template On the card, click **Upload worklist**, then **Download template**. The template is a spreadsheet/CSV with the columns below. | Column | Required | What to put | | :--- | :---: | :--- | | `OfferId` | ✅ | The target private offer, e.g. `offer-abc123`. | | `OfferName` | | Human-readable name. Echoed to the report only. | | `ProductId` | ✅ | The product the offer belongs to. It groups the offers for processing and locates the product's default offer for the list-price fallback. | | `ProductName` | | Human-readable name. Echoed to the report only. | | `MissingDimension` | ✅ | The dimension key to add (must be a dimension already registered on the product). | | `Price` | ✅ | The rate to apply for the dimension. `0` is valid (free dimension). | | `%` | | An audit ratio. Echoed to the report only; it **never** affects the applied price. | ## Step 2 — Fill the worklist - One header row, **values only** (no formulas). For `.xlsx`, only the **first sheet** is read; extra columns are ignored. - One row per `(offer, dimension)` you want to add. An offer that needs several dimensions gets one row per dimension — they are added together in a single update to that offer. - Get the `Price` from the dimension's list price on the product's public listing (see [Pricing Model](/aws-marketplace/pricing-model)). Example worklist — `offer-abc123` gets two dimensions in one update; `offer-def456` gets one: | OfferId | OfferName | ProductId | ProductName | MissingDimension | Price | % | | --- | --- | --- | --- | --- | --- | --- | | offer-abc123 | Acme Annual | prod-xyz789 | Acme Platform | gpu_hours | 2.50 | 100 | | offer-abc123 | Acme Annual | prod-xyz789 | Acme Platform | storage_gb | 0.10 | 100 | | offer-def456 | Beta Co 2-yr | prod-xyz789 | Acme Platform | gpu_hours | 2.50 | 80 | ## Step 3 — Upload Click **Upload worklist**, drag in (or browse to) your `.xlsx` or `.csv`, then **Upload**. :::warning - Accepted file types: `.xlsx` and `.csv`. - Limits: up to **60,000 rows** and **20 MiB** per file. A file missing a required header (`OfferId`, `ProductId`, `MissingDimension`, or `Price`) is rejected immediately — no offer is touched. A row missing its `ProductId` is rejected on its own; the rest of the file still applies. ::: On success you see **"Accepted — applying in the background"**, and a new row appears in the task table on the card. ## Step 4 — Track progress The task table lists every upload, newest first, and refreshes on its own while a task runs. | Status | Meaning | | :--- | :--- | | **Running** | The worklist is being applied. The result shows `processed / total offers`. | | **Completed** | All offers processed. The result shows `✓ applied ⤼ skipped ✗ failed` (counted **by offer**). | | **Cancelled** | You cancelled the task. Offers processed before cancellation keep their outcomes. | | **Failed** | The task could not complete. Any offers processed are still reported. | You can **Cancel** a running task. After you cancel, no **new** offers are submitted; offers already submitted finish and are recorded. ## Step 5 — Download the report For any finished task, click **Report**. The report echoes every input row plus a `Status` and a `Reason`, so every row is accounted for: | Row `Status` | When | Typical `Reason` | | :--- | :--- | :--- | | `applied` | The dimension was added to the offer. | *(empty)* | | `skipped` | Nothing to do for this row. | `dimension already present`, `offer expired / not updatable`, `duplicate row` | | `failed` | The row could not be applied. | `invalid or missing price`, `dimension not registered on product`, `offer listed under a different product`, `AWS: ` | For the sample worklist above, the report might read: | OfferId | MissingDimension | Price | Status | Reason | | --- | --- | --- | --- | --- | | offer-abc123 | gpu_hours | 2.50 | applied | | | offer-abc123 | storage_gb | 0.10 | skipped | dimension already present | | offer-def456 | gpu_hours | 2.50 | failed | offer expired / not updatable | ## How it behaves - **Existing dimensions and prices are never changed.** Only the missing dimensions you list are added. - **Per offer, one update.** All of an offer's requested dimensions are added together, so an offer is updated at most once per upload. - **Expired or non-updatable offers are skipped, not failed.** An offer whose acceptance window has passed with no active agreement cannot be updated by AWS; it is reported as `skipped`. - **Safe to re-run.** If you upload the same worklist again, dimensions already on an offer are `skipped` — re-uploading applies no duplicate changes. - **Unregistered dimensions fail that row only.** A dimension that is not registered on the product is reported `failed` for that row; the offer's other valid rows still apply. ## FAQ ### Does this change the prices of dimensions already on the offer? No. Existing dimensions and their prices are left exactly as they are. Only the missing dimensions you list are added, at the price you set. ### I re-uploaded the same file — will it double-apply? No. Dimensions already present on an offer are reported as `skipped`, so a re-run makes no additional changes. ### Why was my offer reported as "expired / not updatable"? AWS does not allow updating a private offer whose acceptance window has passed when there is no active agreement behind it. Those offers are skipped rather than failed. ### What is the `%` column for? It is carried through to the report for your own audit only. It has no effect on the price that is applied. --- Source: https://doc.fours.com/aws-marketplace/accept-private-offer/ # Accept Private Offer Guidance to accept the private offer as the end buyer in AWS marketplace --- ## Overview This guide provides step-by-step instructions on how to accept a private offer on AWS as the end buyer. It explains how to access the offer, select the desired units, review important details, create a contract, and make the payment. It also mentions the possibility of extending the offer's expiration date and highlights the confirmation email received after accepting the offer. This guide is useful for anyone who has received a private offer on AWS and needs assistance with the acceptance process. ## Before you begin When a typical private offer is negotiated, you pay the entire amount of the offer when you accept it, unless you are using third-party financing. With third-party financing, the financier pays the contract on your behalf and invoices you based on the agreed payment schedule. Before you accept a private offer, verify [permissions](#permissions-to-access-private-offers), [the billing structure for your company](#verify-your-aws-billing), [your payment method for AWS billing](#verify-your-payment-method), and [your tax settings](#verify-your-tax-settings). ### Permissions to access private offers Select one of the following AWS Managed IAM roles based on your need: - `AWSMarketplaceRead-only` to allow permissions to view subscriptions & private offers, but not change or accept. - `AWSMarketplaceManageSubscriptions` to allow permissions to subscribe, unsubscribe & accept private offers. - `AWSMarketplaceFullAccess` to allow complete control of your subscriptions & private offers in AWS marketplace. ### Verify your AWS billing Billing and Cost Management is the service that you use to pay your AWS bill, monitor your usage, and budget your costs. You can use the consolidated billing feature in AWS Organizations to consolidate billing and payment for multiple accounts or multiple Amazon Internet Services Pvt. Ltd (AISPL) accounts. Every organization in AWS Organizations has a management account that pays the charges of all the member accounts. The management account is called a payer account, and the member account is called a linked account. Before negotiating a private offer, verify how your company pays their AWS bill and which AWS account the private offer is made to. ### Verify your payment method Before accepting a private offer, verify that your payment method supports paying the entire cost of the private offer. To verify your payment method, open the Billing and Cost Management console at https://console.aws.amazon.com/billing/. ### Verify your tax settings If your company qualifies for a tax exemption, verify your tax settings. To view or modify your tax settings, sign in to the AWS Management Console and, in your account settings, view the tax settings. For more information on tax registration, see [How do I add or update my tax registration number or business legal address for my AWS account?](https://repost.aws/knowledge-center/update-tax-registration-number). ### Troubleshooting If an error occurs while accepting a private offer or processing payment, please check and address the following 5 potential causes: - Payment method issue, such as missing, invalid, or unsupported. Please [verify your payment method](#verify-your-payment-method) again. - Your Amazon Internet Services Private Limited (AISPL) account limits the use of debit or credit cards for new purchases with a contract pricing model. If you have an AISPL account, contact [AWS Customer Service](https://console.aws.amazon.com/support) to update your default payment method. For more details, see [Restriction on credit and debit card purchases for AISPL customers using AWS Marketplace](https://aws.amazon.com/blogs/awsmarketplace/restriction-on-credit-and-debit-card-purchases-for-aispl-customers-using-aws-marketplace/) at the AWS Marketplace Blog website. - Your private offer includes a payment schedule. However, your default payment method isn't set to `invoicing terms`. :::tip - If you need to update your payment method to invoicing terms, contact [AWS Support](https://console.aws.amazon.com/support/home#/case/create). The following video provides information about the process. - Play the AWS Support video on updating your payment method to invoicing terms ::: - Insufficient permissions. If you don't have the `aws-marketplace:Subscribe` permission to subscribe. The management account must also enable the AWS Billing integration. :::tip - For information about enabling the AWS Billing integration, see [Creating a service-linked role for AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/buyerguide/using-service-linked-roles-purchase-orders.html#create-service-linked-role-purchase-orders). ::: - Purchase order option not available when checking out. The AWS Billing integration is only available for SaaS contracts, professional service products, and server products with contract pricing, and server products with annual pricing for private offers with a flexible payment schedule. ## Step by step guidance ## What Your Buyer Will Receive When you send a private offer, the buyer receives an email with a link to the offer. Here is how the private offer looks on their end: ![What the buyer sees when accepting a private offer](images/aws-what-my-buyer-will-recieve-1.png) 1. **Offer details**: The offer name, who sent it, and its ID. 2. **Contract details**: The contract duration and the specific dimension ("plan" or "tier"). In this example, the dimension reads "Custom Commit; see the attached contract." This is a recommendation for a custom dimension that you can reuse as a template for all private offers, because the details will always live on the EULA (contract). 3. **Additional usage fee**: Makes it clear to your buyer that if they consume extra units (extra users, extra storage, etc.), they will be invoiced for that amount. 4. **EULA (contract)**: The buyer can open and review the EULA you attached when you created the private offer by clicking the blue hyperlink. 5. **Payment schedule**: The total price of the contract. If there are installments, the number of payments and the date each will be invoiced are shown clearly. 6. **Create contract**: After reviewing all the previous details, the buyer clicks **Create contract** and proceeds to payment. :::info - For more on how billing, payments, and tax work for the buyer, see [AWS Marketplace Integration](/aws-marketplace/integration/). ::: ## Private Offer Stuck in "Pending Acceptance" (For Sellers) If a buyer has accepted your offer but the acceptance is not yet reflected in your Fours Console, it may be a sync delay. The Fours Console refreshes every two hours, so there can sometimes be a lag between the cloud marketplace portals and Fours. To force a refresh: 1. Go to **Settings** in your [Fours Console](https://console.suger.io). 2. Select the AWS Marketplace integration. 3. Click **Sync**. This forces Fours to refresh from the marketplace you select. :::tip - If you still cannot find the offer acceptance after syncing, create a support ticket and a Fours teammate will reach out to you. ::: ## After Acceptance: Identifiers on the Offer and Entitlement (For Sellers) Once an offer is accepted, its detail pages carry the AWS identifiers you need when you contact AWS or reconcile records: | Where | Field | What it is | | ----- | ----- | ---------- | | Offer detail | **Partner ID** | AWS Marketplace's own identifier for the offer. | | Entitlement detail | **Partner ID** | AWS Marketplace's own identifier for the entitlement. | | Entitlement detail | **AWS License ARN** | The Amazon Resource Name AWS uses to identify this entitlement. Quote it when you [open an AWS support case](/aws-marketplace/support-cases/) or debug a buyer's access. | Each value has a copy button, and **Partner ID** is also available as a filter on the offer list, so you can search back from an AWS-side identifier to the Fours record. :::info AWS only **Partner ID** and **AWS License ARN** are AWS Marketplace concepts and appear only on AWS offers and entitlements. Azure, GCP, and Oracle records use their own identifiers. ::: :::tip The status chip carries AWS's own wording Fours normalizes every cloud's entitlement statuses to one shared set, so an AWS entitlement that AWS calls `TERMINATED`, `EXPIRED`, or `REPLACED` all show as **Cancelled** in Fours. Hover the status chip to see AWS's own status underneath, labelled **Partner status**. The tooltip appears only when the two differ, so a chip with no tooltip means Fours and AWS agree. ::: ### CPPO entitlements that start in the future A CPPO entitlement whose contract has not started yet is created as `PENDING_START`. Fours promotes it to `ACTIVE` on its own once AWS confirms the agreement's start date has passed — you don't need to touch it, and metering is not enabled before then. Two cases keep an entitlement at `PENDING_START` on purpose: AWS has not reported a start time for the agreement (so the start cannot be confirmed), and the agreement has been deleted on the AWS side. If an entitlement is still `PENDING_START` well after the start date you expect, check the agreement's start date in AWS first — it may have been amended after the entitlement was created. ### Auto-renewal creates a new entitlement (For Sellers) When AWS auto-renews an agreement, Fours does **not** extend the existing entitlement. AWS reports a renewal as a brand-new agreement, and Fours mirrors that: - A **new entitlement** is created for the renewal term, carrying its own agreement ID and its own dates. - The **previous entitlement is cancelled**, so exactly one entitlement is live per AWS agreement at any moment. ```d2 direction: down agreement: "Original agreement\nentitlement ACTIVE" renew: "AWS auto-renews at term end" new: "New entitlement created\nfor the renewal term" old: "Original entitlement cancelled\nafter the final-metering grace period" live: "Exactly one live entitlement\nper AWS agreement" agreement -> renew renew -> new: "AWS reports a new agreement (RENEW)" renew -> old: "AWS reports the old agreement RENEWED" new -> live old -> live ``` Two consequences are worth planning for: - **Downstream systems see a created event and a cancelled event**, not a single update. If your CRM sync, revenue reporting, or notification rules treat "entitlement created" as "new customer", a renewal will now look like one. Key off the buyer or the agreement rather than the entitlement row. - **The cancellation is deliberately delayed.** The old entitlement is cancelled through the same pending-cancel path as any other ending agreement, so you keep the grace period for reporting final metered usage on the term that just ended. Because the renewal is a separate offer and entitlement, the terms fixed on the original offer — including the [buyer net payment term](/aws-marketplace/create-private-offer/#buyer-net-payment-term) — do not carry across automatically. ### Multi-buyer offers get one entitlement per buyer (For Sellers) A private offer can name several buyer AWS accounts. Each account that accepts it gets **its own entitlement** in Fours, attributed to its own buyer record — the offer is shared, the entitlements are not. This matters when you reconcile: filtering by offer on a multi-buyer deal returns several entitlements, one per accepting account, and each has its own agreement ID, dates, and metering. Fours checks the AWS account on the agreement rather than reusing whichever entitlement happens to be attached to the offer, so a second buyer accepting the same offer never lands on the first buyer's entitlement. The same account-level check also completes the historical record where AWS lets an offer sent to one account be accepted by a different linked account: the account that actually held the agreement gets its own entitlement row instead of the record being silently re-pointed. ## Understanding Offer Sub-Status (For Sellers) When monitoring offers in your Fours Console, you may notice a sub-status field that provides additional context about accepted offers. The sub-status helps sellers understand the current state of an offer beyond the main status. ### Purchase Failed Sub-Status An offer may show a `purchase_failed` sub-status when the following conditions are met: - The offer status is **accepted** - All associated entitlements have a **cancelled** status - And each offer's start date and end date are within **one day** **What this means**: This sub-status indicates that while the buyer accepted the offer, the purchase attempt ultimately failed. This typically happens when there was an issue during the payment processing or subscription setup phase, causing the entitlements to be cancelled shortly after creation. **Automatic clearing**: The sub-status is automatically cleared when the above conditions are no longer met. For example, if the entitlement status changes or if new entitlements are successfully created, the sub-status will be removed. If you notice this sub-status on an offer, you may want to reach out to the buyer to resolve any payment or account issues that prevented the successful completion of the purchase. --- Source: https://doc.fours.com/aws-marketplace/revenue/ # Revenue Track billed revenue, partner fees, tax, and disbursements from your AWS Marketplace agreements in Fours. --- ## Overview AWS handles billing on its side — it invoices your buyers, collects payment, deducts its listing/transaction fees and tax, and disburses your earnings to your bank account. Fours does **not** process AWS payments. Instead, Fours **ingests** the billing data AWS publishes through the **AWS Marketplace Data Feed** (delivered to your seller S3 bucket) and normalizes it into unified **revenue records**, so AWS revenue sits alongside your Azure, GCP, and Snowflake revenue in one place. Each AWS billing event carries an **action** (`INVOICED`, `COLLECTED`, `DISBURSED`, `FORGIVEN`) and a **transaction type** (seller revenue share, AWS revenue share = the marketplace fee, AWS tax share, and their refund variants). Fours groups these events by invoice to build one revenue record per invoice. :::info This page focuses on the revenue **data** — what Fours tracks and how each amount is derived. For the finance-team workflow, tax guidance, disbursement settings, and event notifications, see [Finance, Billing, and Tax](/aws-marketplace/finance-billing/). ::: ## Where to find AWS revenue AWS is a first-class channel in Fours' revenue surfaces: 1. Open **Revenue → Revenue Records**. 2. AWS is the default **Channel**; keep it selected (or switch back to it). Two tabs are available: - **Joined Records** — one normalized row per invoice, with billed amount, partner fee, collectable amount, disbursement, tax, and refunds. - **Raw Records** — the individual AWS billing events (each with its action and transaction type) that the joined record was built from. You can also see AWS revenue for a single **buyer** on its detail page, or for a single **entitlement** on its detail view. ## What each amount means Fours derives the normalized revenue record from the AWS billing events for an invoice: | Revenue record field | Derived from | Meaning | |----------------------|--------------|---------| | **Billed (Invoice amount)** | Seller revenue share, invoiced | What AWS billed the buyer. | | **Partner fee** | AWS revenue share | AWS's listing/transaction fee. | | **Listing-fee VAT** | AWS revenue share, tax sub-aggregate | VAT AWS charges **you** on its own listing fee. Stored separately from the partner fee. | | **Tax** | AWS tax share | Tax AWS collected **from the buyer** on the invoice. | | **Collectable** | Invoice − partner fee − tax | What you receive after AWS's fee and tax. | | **Disburse amount** | Disbursed events (failed disbursements excluded) | Money AWS actually paid out to you. | | **Disburse date** | Disbursement event date | When AWS disbursed the funds. | | **Refund (invoice / disburse)** | Seller/AWS revenue-share refund events | Refunded amounts, tracked separately from the original charge. | | **Bank trace ID / disbursement reference** | Disbursement event | Identifiers to reconcile a payout against your bank statement. | A **forgiven** invoice is marked `WRITTEN_OFF` rather than counted as collected. ### Three tax figures, not one An AWS record carries three distinct amounts that all get called "tax" in conversation. They are not interchangeable, and only one of them is money that passes through your hands: | Figure | Charged to | Reaches you? | Counted in the collectable amount? | |--------|------------|--------------|------------------------------------| | **Tax collected & remitted by marketplace** | The buyer | No — AWS remits it to the tax authority itself. | No. Informational only. | | **Tax collected & remitted by seller** | The buyer | Yes — AWS disburses it to you, and **you** remit it onward. | Yes, and it is not deducted again. | | **Listing-fee VAT** | **You** | No — it is part of what AWS keeps. | No. It is stored apart from the partner fee and added only when a tax-inclusive marketplace charge is needed. | The third one is why AWS's partner-fee **amount** and partner-fee **percentage** disagree in [Revenue Records](/revenue/revenue-records/): the amount includes the listing-fee VAT, the percentage deliberately excludes it, and the percentage's base has the seller-remitted tax removed. See [Reading the AWS partner fee](/revenue/revenue-records/#reading-the-aws-partner-fee). ### Buyer payment terms An AWS record **snapshots the net payment term the buyer accepted** on the matching purchase entitlement, so the record keeps reporting the term that was actually agreed even if the buyer's terms change later. AWS supports `P15D`, `P30D`, `P45D`, `P60D`, `P90D`, and `P120D`. Maxima defined on a resale authorization are not resolved into a record — only an accepted term becomes a snapshot. :::info Agreements sold through a **channel partner (CPPO)** are tagged as **Resold** with the reseller's details; direct agreements are tagged **Direct**. ::: ## Sync Fours reads new billing-feed files as AWS delivers them and updates the corresponding revenue records. - The **first** sync performs a historical backfill from your marketplace start date; subsequent syncs re-scan a trailing window so late-arriving events (collections, disbursements, refunds) are picked up. - Revenue for the current day is finalized once AWS delivers the feed, so the newest records may lag by about a day. ## FAQ ### Why is my collectable amount lower than the billed amount? The collectable amount is the billed amount minus AWS's marketplace fee **and** tax. AWS nets both before disbursing your earnings. See [Finance, Billing, and Tax](/aws-marketplace/finance-billing/) for AWS's fee structure and tax handling. ### When will I see a disbursement? A disbursement appears once AWS reports it in the data feed and Fours' next sync ingests it. Until then, the record shows the collectable amount without a disburse date or amount. Failed disbursements are excluded from the disbursed total. ### How are refunds shown? Refunds are tracked as separate refund amounts on the record (refund invoice and refund disburse), so the original charge and the refund remain distinguishable. To process a refund, see [Refunds and Cancellations](/aws-marketplace/refunds-cancellations/). --- Source: https://doc.fours.com/aws-marketplace/buy-with-aws/ # Buy with AWS Put an AWS Marketplace purchase flow directly on your own website. --- ## Overview **Buy with AWS** lets you place an AWS Marketplace purchase flow on your own website. Instead of sending buyers to AWS Marketplace to find your listing, you add a **Buy with AWS** button to your product or pricing page. When a buyer clicks it, they go straight into AWS's procurement flow for your product. Two related buyer-facing elements share the same setup: - **Try with AWS** — surfaces a free trial offer in the same flow, if you have one configured. - **Available in AWS Marketplace** — a badge and source code snippet you add to your site so the **Buy with AWS** and **Try with AWS** buttons render for visitors. :::warning - At present, only SaaS product listings with a subscription pricing model are supported for `Buy with AWS`. - Other product types and pricing models will be made available in the future, following the AWS Marketplace release roadmap. ::: ## Prerequisites - An AWS Marketplace SaaS listing with subscription pricing, already created in Fours. See [Create and publish an AWS Marketplace listing](/aws-marketplace/list-product/). - **Admin** or **Editor** access in Fours. ## Set up the Buy with AWS button ### Open the Buy with AWS settings 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io). 2. Open the AWS listing you want to configure. 3. Click **More actions** in the top-right corner, then select **Buy with AWS**. This opens the **Buy With AWS** dialog, where you get your embed code and configure how the button behaves. ![Buy with AWS option under More actions on an AWS listing](images/aws-set-up-buy-with-aws-on-your-website-1.png) ### Get your embed code At the top of the dialog, under **Demo**, you see a live preview of the **Buy with AWS** button along with the **Available in AWS Marketplace** badge. 1. Click **Source code** to expand the code snippet. 2. Copy the snippet into your website. Once added, the **Buy with AWS** and **Try with AWS** buttons render on your product page, along with the **Available in AWS Marketplace** badge. ![Source code snippet for the Buy with AWS button and Available in AWS Marketplace badge](images/aws-set-up-buy-with-aws-on-your-website-2.png) ### Configure the button behavior Below the demo, fill in the following fields to control what happens when a buyer clicks the button: | Field | What it does | | --- | --- | | Buy with AWS URL | Redirects buyers to the AWS Marketplace procurement page for your product, and for a specific offer if one is selected below. | | Public or Private Offer | Optional. Choose a specific private or public offer to show the buyer, including its pricing and legal terms. If left blank, all offers available to the buyer are shown, newest to oldest. | | Free Trial Offer | Optional. Choose a free trial offer to show the buyer. If left blank, all available offers are shown, newest to oldest. This is what powers the **Try with AWS** experience. | | Request Private Offer | Optional. Select a workflow to let the buyer request a private offer directly from you. | | Source URL | Optional. Used in the co-branded page's breadcrumb bar and cancel button to send the buyer back to the page they came from. Must be registered in AWS Marketplace, and passed using URL encoding. | ### Add UTM tracking (optional) To track traffic from the Buy with AWS button in your marketing analytics, fill in any of the following: | Field | What it does | | --- | --- | | UTM Content | Urchin Tracking Module (UTM) content parameter for tracking traffic to a specific website. | | UTM Medium | UTM medium parameter for tracking traffic to a specific website. | | UTM Source | UTM source parameter for tracking traffic to a specific website. | | UTM Campaign | UTM campaign parameter for tracking traffic to a specific website. | ## Try with AWS **Try with AWS** shares the same dialog and button placement as Buy with AWS, but surfaces a free trial offer instead of a paid one. It activates when you select a **Free Trial Offer** in the settings — once selected, a `Try with AWS URL` becomes available. ## Available in AWS Marketplace To showcase your products as **Available in AWS Marketplace**: - **Copy the source code**: Insert the Fours-provided source code snippet into your website. - **Display the buttons**: The **Buy with AWS** and **Try with AWS** buttons appear on your product pages, along with the **Available in AWS Marketplace** badge. ## Frequently Asked Questions ### Can I use Buy with AWS for any product type? No. It is currently limited to SaaS listings with subscription pricing. AWS may expand support to other types in the future. ### What is the difference between Buy with AWS and Try with AWS? They share the same dialog and button placement. Try with AWS surfaces a free trial offer instead of a paid one — it activates when you select a **Free Trial Offer** in the settings. ### Do I need to fill in every field? No. Only **Buy with AWS URL** is required to get a working button. Offer selection, private offer requests, source URL, and UTM fields are all optional. --- Source: https://doc.fours.com/aws-marketplace/deployed-on-aws-badge/ # Deployed on AWS Badge Understand what the "Deployed on AWS" badge means, how AWS determines eligibility, and how to submit your architecture for review. --- :::info This page is a quick-reference overview. AWS's own documentation is the source of truth for the current, complete requirements — see [SaaS product guidelines](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-guidelines.html#march-saas-guidelines) and [Update architecture details](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-product-settings.html#updating-architecture-details). ::: ## Overview The AWS Deployed badge is a designation AWS applies to eligible AWS Marketplace products that run entirely on AWS infrastructure. It helps buyers quickly identify products that are deployed on AWS and whether they align with their AWS procurement and cloud governance requirements. The badge appears on your AWS Marketplace listing and in search results. ![The "Deployed on AWS" badge shown on an AWS Marketplace listing](images/aws-understand-the-deployed-on-aws-badge-1.png) To learn more, see the [AWS announcement (May 2025)](https://aws.amazon.com/blogs/awsmarketplace/aws-marketplace-announces-upcoming-expansion-to-saas-product-catalog/). :::info The badge is not required to publish or sell on AWS Marketplace. If enterprise buyers are an important part of your go-to-market strategy, it is often worth pursuing. ::: ## Why the badge matters The badge can have a direct impact on how buyers evaluate and purchase your product. ### It can help you win enterprise deals Many large companies pre-commit to spending a certain amount with AWS through programs such as Enterprise Discount Programs (EDPs) and Private Pricing Addendums (PPAs) — negotiated spend commitments in exchange for discounts. When a buyer with one of these agreements purchases your product, they usually want that purchase to count toward it, and only badged products qualify. If your buyers don't have (or don't prioritize) an AWS spend commitment, this may not matter much to your go-to-market. ### It builds buyer confidence For procurement, security, and cloud governance teams, the badge provides a quick indication that AWS has reviewed the architecture information associated with the product and determined that it qualifies for the designation. ## Requirements At a high level, AWS needs to verify one thing: **your product runs entirely on AWS.** There's no partial credit — if any part of either plane runs somewhere else, even a small part, the product doesn't qualify. To qualify for the AWS Deployed badge: - Your **application plane** (where customer workloads and data are processed) runs on AWS — in your account, the buyer's account, or both. - Your **control plane** (where you manage, operate, and provision the product) also runs on AWS. - Any third-party services that store, process, or transmit customer application data also run on AWS — with three documented exceptions: content delivery networks (CDNs), DNS services, and corporate identity providers (like Okta or Azure AD). - Agents or gateways used for security, monitoring, data replication, or migration are allowed to run outside AWS (including on-premises), as long as they only send data to AWS for storage and analysis. You demonstrate this by submitting an architecture diagram as part of your AWS Marketplace listing. For more details, see [AWS's architecture guidelines](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-guidelines.html#march-saas-guidelines). :::info The AWS Deployed badge does not require an AWS Foundational Technical Review (FTR), AWS Competency, or SOC 2 certification. AWS evaluates the product's deployment architecture separately from those programs. ::: ## Prepare your architecture diagram Your diagram (PNG or JPG) should: - Group and label every component as either **application plane** or **control plane**. - Show where each component physically runs — your AWS account, the buyer's AWS account, or elsewhere. - Focus on logical structure — components don't need to name specific AWS or third-party services. You can submit a high-level diagram (main components and data flows) or a low-level, detailed one — both are acceptable. See AWS's [full diagram guidance and examples](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-guidelines.html#arch-diagram) for the complete criteria. :::info You cannot make this diagram public once submitted — AWS reviews it, but it's never shown to buyers. ::: ## Submit your architecture details Condensed from AWS's own [Update architecture details](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-product-settings.html#updating-architecture-details) guide — check that page directly if these steps ever look out of date. 1. Sign in to the [AWS Marketplace Management Portal](https://us-east-1.console.aws.amazon.com/partnercentral/home). 2. On the **Build** menu, choose **SaaS**, then select your product from the **SaaS products** table. 3. From the **Request changes** dropdown, choose **Update architecture details**. 4. Choose the hosting pattern that matches your architecture. If the pattern you choose is one AWS considers deployed on AWS, you'll be prompted for two more things: - Upload your architecture diagram. - Specify where your **application plane** runs (your account, the buyer's account, or both). 5. Choose **Update architecture details** to submit. ### Track your request - To check status, choose your product in the **SaaS products** table, then open the **Request log** tab — it shows as **Under review**, then updates to **Succeeded** once AWS finishes. - To see your actual assessment result, open the **Architecture details** tab on the same product. There's no fixed published turnaround time. Your listing only needs to exist in the portal — it doesn't need to be publicly live — so you can submit while it's still in `Limited` status, which gives you time to address any AWS feedback before you go public. :::info If your hosting pattern changes after you've received the badge, you're required to update your architecture details again — the badge reflects your current, submitted architecture, not a one-time snapshot. ::: ## If you don't qualify yet This is normal, especially if any part of your stack touches a third-party service that isn't AWS-native. Your options: - **Migrate the non-AWS component onto AWS.** A common example: if you call an external AI inference API, moving that call to a native AWS service such as **Amazon Bedrock** can resolve this while keeping similar model capabilities — one path forward, not the only one. - **Decide you don't need the badge.** If your buyers aren't drawing down AWS spend commitments, there's no real downside to skipping this and listing normally. ## Frequently asked questions ### Can I sell on AWS Marketplace without the badge? Yes. The badge is optional and is not required to publish or transact through AWS Marketplace. ### When should I submit my architecture for review, before or after my listing goes live? Your listing needs to exist in the AWS Marketplace Management Portal (AMMP), but it does not need to be publicly live. You can submit architecture details as a change request for listings that are still in a `Limited` state. If earning the badge is important for launch, consider submitting while your listing is still in `Limited` so you have time to address any feedback from AWS. ### My product uses third-party services. Can I still qualify? It depends on what those services do with your buyers' data. AWS allows the following outside of AWS with no conditions: CDNs, DNS services, and corporate identity providers (like Okta or Azure AD). Security/monitoring agents and gateways are also allowed outside AWS as long as they only send data to AWS. For more details, see the [SaaS architecture guidelines on AWS](https://docs.aws.amazon.com/marketplace/latest/userguide/saas-guidelines.html#saas-architecture). ### What does the review process look like? AWS does not publicly document the review process for the badge. What AWS does describe is the submission process — you update your architecture details and upload your diagram in the AMMP, and AWS reviews what you have submitted. If you have questions about review status or timelines, contact your AWS Marketplace representative or reach out to AWS Seller Operations directly. ### What if my hosting pattern changes after I get the badge? You're required to update your architecture details if your hosting pattern changes. The badge reflects your current, submitted architecture — it isn't a one-time assessment you can drift away from. ### Do I need to submit architecture details for every listing? Yes. AWS evaluates eligibility separately for each AWS Marketplace product. Qualifying one listing does not automatically qualify your other listings. If you have multiple products, you need to submit architecture details for each one individually. --- Source: https://doc.fours.com/aws-marketplace/finance-billing/ # Finance, Billing, and Tax A guide to help your finance team navigate revenue, disbursements, notifications, and tax on AWS Marketplace using the Fours Console. --- ## Overview This guide helps your finance team use the Fours platform effectively. It covers the key console pages for tracking revenue, how to set up event notifications, and essential information about AWS billing, disbursements, and taxes. :::info - Fours does **not** process payments or perform tax calculations. These functions are handled exclusively by AWS. If you encounter payment issues, such as disbursement delays, contact AWS directly by submitting a Support ticket. ::: For convenience, you can grant finance team members **Viewer** access to the console. For more on user roles, see the [Account and organization roles](/get-started/account/#organization) documentation. ## Inside the Fours Console ### Entitlement ![Entitlement page showing contract details and revenue data](images/aws-aws-finance-guide-billing-payments-and-t-1.png) The **Entitlement** page provides a detailed view of contract-specific data. Here's what you can access: **Overview:** - Agreement ID - Entitlement Type - Auto Renew - Start Date and End Date - Term Length **Buyer Information:** - Account ID - Company Name - Email Domain - Location **Revenue Details:** - Entitlement Terms - Invoice Date - Invoice Amount - Partner Fee - Collectable Amount - Due Date - Disburse Date - Disburse Amount - Refund :::tip - You can configure the visible columns using the gear icon in the table settings. ::: ### Revenue ![Revenue tab showing marketplace contract revenue](images/aws-aws-finance-guide-billing-payments-and-t-2.png) On the **Revenue** tab, you can: - Visualize the complete revenue data of all marketplace contracts. - Filter the data by cloud provider or time period. - Export revenue data to a CSV file for further analysis. ### Analytics The **Analytics** page provides advanced insights into your financial data. Explore detailed metrics and trends to make informed decisions. Learn more in the [Analytics](/analytics/) documentation. ## Event Notifications You can configure email and Slack notifications to keep the finance team informed about key events. Examples include: - Entitlement creation - New disbursements from AWS To set up notifications, see: - [Email notification setup](/settings/email-notification/) - [Slack notification setup](/integrations/slack/) Example of an email notification: ![Example email notification](images/aws-aws-finance-guide-billing-payments-and-t-3.png) Examples of Slack notifications: ![Example Slack notification](images/aws-aws-finance-guide-billing-payments-and-t-4.png) ![Example Slack notification](images/aws-aws-finance-guide-billing-payments-and-t-5.png) ## Flow of Events The flowchart below shows how a contract moves from acceptance through invoicing, buyer payment, and disbursement: ![Flowchart of billing and disbursement events](images/aws-aws-finance-guide-billing-payments-and-t-6.png) ## Tax Information Fours does not handle tax calculations. For official AWS tax information, see [AWS Tax Help](https://aws.amazon.com/tax-help/). Whether you need to charge and remit taxes separately depends on the buyer's country. In countries such as the USA, where the marketplace is responsible for collecting and remitting taxes, AWS handles this for you. In other countries, such as France, the seller must collect the tax manually. See [AWS Marketplace tax help for sellers](https://aws.amazon.com/tax-help/marketplace-sellers/) for details on product types, supported countries, and the process. ## Additional AWS Resources These AWS resources can help your finance team understand the underlying processes: - [AWS Disbursements (video)](https://youtu.be/C0DPSRYO-kQ?feature=shared) - [AWS Buyer Invoicing (video)](https://youtu.be/vKzo7FINzss?feature=shared) ## FAQ ### Who do I receive the payment from? Payment is always deposited into your registered bank account. To check your registered bank account, visit [AWS Marketplace Management Portal Settings](https://aws.amazon.com/marketplace/management/seller-settings/account) > Payment Information. ### How much listing/transaction fee does AWS take? Listing fees depend on the type of listing, the TCV of the offer, and the type of offer. AWS's [Listing and transaction fees](https://docs.aws.amazon.com/marketplace/latest/userguide/listing-fees.html) document covers the fee structure for all scenarios. ### When is the customer billed? AWS bills the customer in one of three ways: 1. Date of subscription acceptance (upfront billing). 2. Custom payment schedule (private offers built with the flexible payment scheduler). 3. Metered usage, billed on the second and third day of the month for the prior month's usage. ### When will I receive money from AWS? Every customer agrees to net payment terms with AWS — commonly net 30, 45, or 60, and net 0 for credit cards. Once a customer receives the bill, they must pay within the agreed terms. A private offer can override the buyer's account-level terms with its own **Buyer net payment term** — Net 15, 30, 45, 60, 90, or 120 days. Longer terms push out the date AWS collects, and therefore the date AWS disburses to you. See [Buyer net payment term](/aws-marketplace/create-private-offer/#buyer-net-payment-term). Every seller has a disbursement cycle, which you can set up under settings. There are two cycles: daily and monthly. You can receive the money as soon as AWS receives it, or on a specific date every month. To review your settings, visit [AWS Marketplace Management Portal Settings](https://aws.amazon.com/marketplace/management/seller-settings/account) > Payment Information > Update Banking Information > Disbursement Preference. ### Do I need to charge and remit taxes separately? This depends on the buyer's country. In countries such as the USA, where the marketplace is responsible for collecting and remitting taxes, AWS handles this. In other countries, such as France, the seller must collect the tax manually. See [AWS Marketplace tax help for sellers](https://aws.amazon.com/tax-help/marketplace-sellers/) for more details. ### What should we do if there is a delay in receiving payments from AWS? Create a ticket with AWS Support using the [AWS Marketplace contact page](https://aws.amazon.com/marketplace/management/contact-us/). ### How do I process refunds? You can process a full or partial refund to the buyer by submitting the [AWS Marketplace refund request form](https://aws.amazon.com/marketplace/management/support/refund-request). You can request a refund even when the buyer has not yet paid the invoice. In the additional comments section, mention that the charges should be waived if they are unpaid. ### Can I invoice a customer in their currency? As a seller, you create private offers in US Dollars ($). AWS then checks the buyer's currency based on their account ID and payment settings and bills them in their currency. AWS uses exchange rates published by Bloomberg every day. See the [list of supported currencies](https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-paying-for-products.html#supported-currencies). For multi-currency accounts, see [Multi Currency](/aws-marketplace/create-private-offer/#multi-currency). ### How can I change the type of disbursement? 1. Log in to the AWS Marketplace Management Portal and go to the **Settings** tab. ![Settings tab in AWS Marketplace Management Portal](images/aws-aws-finance-guide-billing-payments-and-t-7.png) 2. Select the **Payment Information** tab. ![Payment Information tab](images/aws-aws-finance-guide-billing-payments-and-t-8.png) 3. Click **Update Banking Information**. ![Update Banking Information button](images/aws-aws-finance-guide-billing-payments-and-t-9.png) 4. Scroll down to the **Disbursements** option and select the desired disbursement option (daily or monthly). --- Source: https://doc.fours.com/aws-marketplace/refunds-cancellations/ # Refunds and Cancellations AWS Marketplace now offers sellers a streamlined self-service process for refunds and agreement cancellations, reducing the time and effort required to process these requests. This new capability eliminates the need to file support tickets, and gives sellers full visibility into the latest status of each request. --- ## Overview With this launch, sellers can: - **Request refunds or cancellations** directly from the Entitlements page in the Fours Console - **Pre-populated requests** — Refund and cancellation requests are automatically pre-populated with agreement and invoice data - **Track every request** from submission through completion :::info Availability Seller self-service refunds and agreement cancellations are available in all [commercial AWS Regions](https://docs.aws.amazon.com/marketplace/latest/buyerguide/supported-regions.html) where AWS Marketplace is supported. ::: --- ## Seller Self-Service Refunds Sellers can now process refunds directly without contacting AWS support. ### How It Works 1. **Submit refund request** — Sellers request refunds from the Entitlements page in the Fours Console 2. **Automatic processing** — Billing adjustments are processed automatically 3. **Flexible options** — Sellers can: - Refund charges on paid invoices - Reduce outstanding balances on unpaid invoices ![Refund request in Fours Console](/img/aws/entitlement_refund.png) :::warning Irreversible Refunds are irreversible once processed by AWS. Double-check the amount and invoice before submitting. ::: ### Invoices you must refund in the AWS console Some invoices cannot be refunded through Fours at all, and Fours tells you before you try rather than after AWS rejects the request. For invoices issued in jurisdictions where AWS applies KYC rules — most commonly those invoiced by **Amazon Web Services EMEA SARL** — AWS requires the refund to be submitted by a KYC-verified user with MFA. Fours submits through an assumed integration role, which by design can never be a verified human user, so those refunds have to be made by a person in the AWS Marketplace console. In the **Billing Adjustment** dialog, such an invoice is listed like any other, but its checkbox is disabled and the row says why: **"Issued by AWS EMEA SARL — AWS requires a KYC-verified user to adjust it."**, followed by a **Must be adjusted in AWS ↗** link. If every invoice on the billing term is restricted, the dialog title reads **Billing Adjustment — KYC required** and the same explanation appears above the table with a **Complete adjustment in AWS Partner Central ↗** link, so you know immediately that this term cannot be adjusted from Fours. Each of these links opens the agreements list of the AWS Marketplace Management Portal in a new tab. It is an ordinary link — Fours does not sign you in — so sign in as your KYC-verified AWS user, open the agreement, and make the adjustment there. A small number of other jurisdictions carry the same requirement without being flagged in advance. For those, Fours submits the request, and when AWS refuses it for this reason the request fails with: *"This invoice can only be adjusted by a KYC-verified user with MFA. Please submit the billing adjustment in the AWS Marketplace console."* The entitlement's **Adjustment History** table shows each request's full **Status Message**, and when AWS refused a request for KYC or MFA reasons, the row adds the same explanation and **Must be adjusted in AWS ↗** link. You can also use the [AWS refund form](#submit-a-refund-or-cancellation-via-the-aws-refund-form) below. --- ## Agreement Cancellations Sellers can now submit cancellation requests directly. ### How It Works 1. **Submit cancellation request** — Seller submits a cancellation request from the Entitlements page 2. **Buyer notification** — The buyer receives a notification and has **seven (7) days** to respond 3. **Auto-proceed** — If there is no response within 7 days, the cancellation proceeds automatically ![Cancellation request in Fours Console](/img/aws/entitlement_cancel.png) --- ## Submit a Refund or Cancellation via the AWS Refund Form If you cannot use the self-service flow above, refunds and contract cancellations can also be handled by the AWS Customer Service team through the AWS refund/cancellation form. As the seller (the ISV for a standard private offer, or the channel partner for a CPPO), you initiate the refund and/or contract cancellation request via the [AWS refund/cancellation form](https://aws.amazon.com/marketplace/management/support/refund-request). A [walkthrough video](https://www.youtube.com/watch?v=eQpadPl0ROs) covers the entire process. Enter the following details on the form: - **Buyer account ID** — Found in the offer detail or on the Billed Revenue Dashboard. This must be the subscriber account ID. - **Seller account ID** — The seller's AWS account ID used to create the private offer. - **Product ID** — Found in the offer detail or on the Billed Revenue Dashboard (Legacy Product ID column). - **Billing date** — Found in the offer detail or on the Billed Revenue Dashboard (Usage Begin Period column). - **Refund amount** — If a refund is not required, set this to $0. - **Additional details** — For a contract cancellation, include text such as `Please cancel account X's subscription to offer-X`. For a refund, specifying the buyer's AWS invoice ID here helps Customer Support (for example, `This refund targets invoice ID 123`) — it is helpful but not mandatory. :::tip Once the request is submitted, AWS generates a reference ID and displays it on screen. Save this reference ID in case you need to follow up. ::: --- ## Related Documentation - [AWS Marketplace Seller Guide - Refunds and Cancellations](https://docs.aws.amazon.com/marketplace/latest/userguide/refunds.html) --- Source: https://doc.fours.com/aws-marketplace/bedrock-managed-entitlements/ # Bedrock Managed Entitlements Set up managed entitlements so contracted pricing from a Bedrock private offer applies across every account in your AWS Organization, not just the payer account. --- ## Overview When a buyer accepts a Marketplace private offer for a third-party Amazon Bedrock model (for example, Anthropic Claude), the contracted pricing applies only to the **payer account**. If member accounts across the AWS Organization also use the model, they're billed at **list price** unless managed entitlements is enabled. Managed entitlements uses **AWS License Manager** to distribute the license from the payer account to member accounts, so contracted pricing applies everywhere the model is used. | Without managed entitlements | With managed entitlements | | --- | --- | | Private offer on the payer account, usage on member accounts, member accounts billed at list price | Private offer on the payer account, license distributed to member accounts via grants, contracted pricing applies to all usage | :::info All license resources are managed in **us-east-1 (N. Virginia)**, regardless of where usage actually occurs. Switch your console to us-east-1 for every step below. ::: ## Before You Begin Make sure you have: - An **AWS Organization** with all features enabled - Access to the **management account** (or a delegated admin account) - At least one third-party Bedrock model subscription via AWS Marketplace - Service-linked roles for License Manager and Marketplace (created during setup below) ## Step 1: Determine If You Need a Delegated Administrator 1. If you'll manage licenses directly from the management account, skip to Step 2. 2. If your management account is restricted (common in large enterprises and banks), designate a delegated administrator: 1. Sign in to your management account. 2. Open the **AWS License Manager** console. 3. In the navigation pane, choose **Settings**. 4. Under **Delegated administrator**, enter the AWS account ID of the member account you want to designate. 5. Choose **Save changes**. Once designated, the delegated admin completes Steps 2 and 3 from their own account. ## Step 2: Enable Service-Linked Roles and Trusted Access Enable trusted access and create service-linked roles for both License Manager and Marketplace. ### Set up AWS License Manager 1. Sign in to your management account. 2. Open the **AWS License Manager** console. 3. Confirm you're in the **us-east-1 (N. Virginia)** region. 4. When the console first loads, a popup asks you to create a service-linked role — choose **Create service-linked role**. 5. In the navigation pane, choose **Settings**. 6. Under **Account management**, choose **Link AWS Organization accounts**. 7. Confirm the status shows **Linked**. ### Set up AWS Marketplace 1. While still signed in to your management account, open the **AWS Marketplace** console. 2. In the navigation pane, choose **Settings**. 3. Under **AWS License Manager Integration**, choose **View setting details**. 4. Select both checkboxes: - **Enable trusted access across your organization** - **AWS Marketplace license management service-linked role for this account** 5. Choose **Create integration**. 6. Confirm the settings show **Successfully created** for both **Service-linked role** and **Trusted access**. :::warning Enabling trusted access from the management account automatically creates service-linked roles for **all** member accounts in your organization. ::: ## Step 3: Distribute Licenses (Create Grants) 1. Sign in to your management account (or delegated admin account). 2. Open the **AWS License Manager** console. 3. Confirm you're in **us-east-1**. 4. In the navigation pane, choose **Granted Licenses**. 5. Select the license you want to share. 6. Choose **Create grant**. 7. Enter a descriptive grant name. 8. To grant access to the whole organization, enter the **Organization ID** (starts with `o-`). 9. Choose **Create grant**. :::tip For organizations with all features enabled, grants are auto-accepted and appear in a **Disabled** state — no manual acceptance required. ::: ## Step 4: Activate Grants The activation workflow depends on your AWS Organizations configuration. ### If your organization has all features enabled (recommended) 1. Sign in to the management account (or delegated administrator account). 2. Open the **AWS License Manager** console. 3. In the navigation pane, choose **Granted Licenses**. 4. Select the grant to activate — for organization-wide grants, select the **parent grant**. 5. Choose **Activate**. 6. Confirm the activation. This activates the grant for all recipient accounts at once. Verify individual account statuses on the grant details page under **Grants**. ### If your organization uses consolidated billing only Grants appear in a **Pending Acceptance** state in each recipient account, and each recipient must accept and activate individually: 1. Sign in to the recipient member account. 2. Open the **AWS License Manager** console in **us-east-1**. 3. In the navigation pane, choose **Granted Licenses**. 4. Select the grant. 5. Choose **Accept & Activate**. After activation, contracted pricing applies to all Bedrock model usage in those accounts. ## Troubleshooting | Issue | Possible cause | Resolution | | --- | --- | --- | | Member account still billed at list price | Grant hasn't been created or activated for that account | Check the grant's status under **Granted Licenses**. Create and activate the grant if it doesn't exist. | | Grant stuck in "Pending Acceptance" | Organization uses consolidated billing only, which requires manual acceptance per account | Sign in to the recipient account and choose **Accept & Activate** from **Granted Licenses**. | | Can't find license resources in your working region | License resources are only managed in us-east-1 | Switch to the **us-east-1 (N. Virginia)** region in the console. | | Delegated admin can't complete setup | Delegated admin wasn't designated before starting Step 2 | Complete Step 1 (designate a delegated admin in the management account) before proceeding. | ## FAQ ### Is this a one-time setup? Yes — setup is a one-time process per organization. ### Do new accounts joining the organization need manual setup? No. New accounts automatically receive org-wide grants. ### Can a grant be revoked later? Yes. Grants can be deactivated or deleted at any time through License Manager. ### Which region should I use for all of this? **us-east-1 (N. Virginia)** — all license resources are managed there regardless of where usage occurs. ## Related Resources - AWS documentation: [Amazon Bedrock managed entitlements overview](https://docs.aws.amazon.com/bedrock/latest/userguide/managed-entitlements.html) --- Source: https://doc.fours.com/aws-marketplace/migrate-to-aws-partner-central/ # Migrate to AWS Partner Central 3.0 Migrating to AWS Partner Central 3.0 (PC3) moves your AWS Partner Central experience into the AWS Management Console, giving your team a single place to access co-selling, funding, and Marketplace partner tools. This guide walks you through the steps required to complete the migration, including setting up the required user access and permissions. --- :::info This migration only changes **how your team accesses AWS Partner Central** in the AWS Console. It doesn't affect your AWS ACE integration with Fours or change how opportunity data is synced. If you're still using the legacy S3 integration for AWS ACE, that upgrade must be completed separately — see [Migrate from S3 to the Partner Central API](/integrations/aws-ace-migration-from-s3-to-api/). ::: ## Prerequisites ### Gather your team This process touches core AWS account settings and user permissions. Make sure these three roles are available before you begin: - **Alliance Lead or Cloud Admin**: The primary account owner in AWS Partner Central. This person must have the authority to accept AWS Partner Network terms and conditions on behalf of your company. The Alliance Lead can delegate account linking to a user with the Cloud Admin role. - **IAM Administrator**: Manages user permissions through IAM. Typically sits in IT Security, Information Security, or Governance and Compliance. Responsible for implementing IAM policies, configuring SSO solutions, and maintaining role-based access control. ### Plan your migration window Schedule your migration for a preferred date and time outside your normal business hours to minimize disruption. Partner Central will be unavailable to all users once the migration begins, and the migration typically takes 2–6 hours, depending on the amount of data required to transfer. The alliance lead will receive an email notification when the migration is complete. :::warning - The migration cannot be canceled once scheduled and can only be rescheduled up to 24 hours before the scheduled time. ::: ## Step 1: Check your migration status 1. Log in to the [legacy AWS Partner Central portal](https://partnercentral.awspartner.com/partnercentral2/s/login) using your Alliance Lead or Cloud Admin credentials. 2. Check whether a migration banner or instructions are still shown. - If you still see migration prompts or a banner, your account has not migrated yet. Click **View instructions**. - If no migration prompts appear, your account has likely already been migrated. ![The migration banner and View instructions button in the legacy AWS Partner Central portal](images/aws-migrate-to-aws-partner-central-1.png) ## Step 2: Complete the migration tasks After you click **View instructions**, a new tab opens with your migration checklist. You need to complete three tasks before you can run the migration. ### Task 1: Identify a primary AWS account for Partner Central This step confirms which AWS account is linked to AWS Partner Central. **If an AWS account is already linked:** 1. Review the account details shown on the page. 2. Make sure the displayed account is the one you want to use with AWS Partner Central. ![Task 1: the primary AWS account linked to AWS Partner Central](images/aws-migrate-to-aws-partner-central-2.png) :::warning The linked account **can't be changed after migration**. If the account is incorrect, don't continue — see [Unlinking AWS Partner Central and AWS accounts](https://docs.aws.amazon.com/partner-central/latest/getting-started/unlinking-apc-aws-marketplace.html) for the full impact and steps to unlink. ::: **If no AWS account is linked:** Select the AWS account you want to use with AWS Partner Central. Choose carefully, as this account can't be changed after migration. For help choosing the right account for your setup, see [Select an AWS account for AWS Partner Central](https://docs.aws.amazon.com/partner-central/latest/getting-started/linking-prerequisites.html#which-accounts-to-link). ### Task 2: Link your AWS account with your Partner Central account Once you've identified your primary account, link it to your APN account. Your Alliance Lead or Cloud Admin must complete this step. For step-by-step instructions, see [Linking AWS Partner Central and AWS accounts](https://docs.aws.amazon.com/partner-central/latest/getting-started/linking-apc-aws-marketplace.html). ![Task 2: linking your AWS account with your Partner Central account](images/aws-migrate-to-aws-partner-central-3.png) ### Task 3: Onboard users to IAM All Partner Central users need AWS account access to use the new Partner Central. Without this step, sales executives, ACE managers, and other users will be locked out after migration. Your **Alliance Lead** initiates this step. Your **IAM Administrator** handles the actual permission assignments. 1. Click **Onboard users**. This opens the *User onboarding* page. ![Task 3: the User onboarding page in AWS Partner Central](images/aws-migrate-to-aws-partner-central-4.png) 2. Work with your IAM Administrator to select the onboarding option that matches how your organization manages user access: - **AWS IAM Identity Center** (recommended): Use this if you want to set up single sign-on and centralize user management across AWS accounts. - **External identity provider (IdP)**: Use this if your organization already uses an external IdP such as Okta, Azure AD, or Ping Identity to manage user access. - **AWS IAM**: Use this for smaller teams who prefer to onboard users individually without SSO. If your IAM Administrator needs help setting up any of these options, see [Controlling access in AWS Partner Central](https://docs.aws.amazon.com/partner-central/latest/getting-started/controlling-access-in-aws-partner-central.html) for step-by-step guidance on all three. 3. In the *Onboarding guide – AWS IAM Identity Center* section, click **Download partner user list**. This exports a CSV file of all your existing Partner Central users along with their current roles. ![Download partner user list button on the User onboarding page](images/aws-migrate-to-aws-partner-central-5.png) 4. Open the CSV file and review each user's current role assignment and last login date. Decide which users still need access in the new experience. :::tip Scroll to column I to see the recommended IAM policy for each user based on their current role. ::: ![Column I of the exported CSV showing the recommended IAM policy per user](images/aws-migrate-to-aws-partner-central-6.png) 5. Work with your IAM Administrator to assign each user the correct managed policy based on their role. For the full policy reference, see [AWS managed policies for AWS Partner Central users](https://docs.aws.amazon.com/partner-central/latest/getting-started/managed-policies.html). 6. Once your IAM Administrator has finished setting up permissions, make sure every user knows how to sign in. How they access Partner Central depends on the onboarding option you chose above. 7. After all users have been onboarded, return to the *User onboarding* page, check the confirmation box, and click **Save changes**. ![Confirmation checkbox and Save changes button on the User onboarding page](images/aws-migrate-to-aws-partner-central-7.png) ## Step 3: Start and complete the migration 1. Go back to the Migration Instructions page. 2. Scroll all the way to the bottom of the page. 3. Select **Choose migration options**. A confirmation box appears. ![Choose migration options button at the bottom of the Migration Instructions page](images/aws-migrate-to-aws-partner-central-8.png) 4. Choose one of: - **Migrate now**: Starts the migration immediately after you confirm. Use this if your team is ready and you've already alerted all users. - **Schedule for later**: Lets you select a future date and time for the migration to run. Use this if you want to plan the migration window in advance. 5. Type the required confirmation text, then click **Migrate now**. ![Migration confirmation box with Migrate now and Schedule for later options](images/aws-migrate-to-aws-partner-central-9.png) AWS shows a processing screen, and the migration may take several hours to fully complete. During this time, users can't access the existing Partner Central portal. ![AWS migration in-progress processing screen](images/aws-migrate-to-aws-partner-central-10.png) ## Step 4: Confirm migration is complete 1. Sign in to the [AWS Management Console](https://console.aws.amazon.com/). 2. In the search bar at the top of the page, type **Partner Central**, then click **AWS Partner Central**. ![Searching for Partner Central in the AWS Management Console](images/aws-migrate-to-aws-partner-central-11.png) 3. Look for a green checkmark next to **Partner Account Status: Active**. ![Partner Account Status showing Active with a green checkmark](images/aws-migrate-to-aws-partner-central-12.png) ## Step 5: Validate user access This step is done by two people working together: the **IAM Administrator** checks that permissions are correctly set up on the AWS side, and the **Alliance Lead** coordinates with a small group of test users to confirm they can actually sign in and use Partner Central. ### Part A: IAM Administrator checks permissions 1. Sign in to the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon). 2. In the left navigation pane, under **Multi-account permissions**, select **AWS accounts**. 3. Select the AWS account linked to Partner Central. 4. Confirm that each required user or group has the correct permission set attached. Cross-reference against the reviewed user list from Task 3. 5. If any user is missing a permission set, assign it now before asking them to test sign-in. See [Assign user or group access to AWS accounts](https://docs.aws.amazon.com/singlesignon/latest/userguide/assignusers.html) for instructions. ### Part B: Test user sign-in Ask 2 to 3 users representing different role types — for example, one Cloud Admin and one ACE team member — to sign in and verify access. How they sign in depends on the onboarding option set up in Task 3: - **AWS IAM Identity Center**: Sign in through the [AWS access portal](https://docs.aws.amazon.com/singlesignon/latest/userguide/using-the-portal.html) using the SSO link provided by the IAM Administrator. - **External identity provider (IdP)**: Sign in through your organization's IdP console, then select the linked AWS account. - **AWS IAM**: Sign in to the [AWS Management Console](https://console.aws.amazon.com/) using the IAM credentials provided by the IAM Administrator. Each test user should confirm: - The Partner Central dashboard loads successfully. - Their ACE opportunities and historical data are visible. - They can access the features their role is supposed to allow. ### Part C: Troubleshoot access issues If a user can't sign in or sees missing features after migration, the most common cause is an incorrect or missing IAM policy assignment. The IAM Administrator should: 1. Return to the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon) and confirm the user's permission set is attached and provisioned to the correct AWS account. 2. Check that the managed policies assigned match the user's intended role. See [AWS managed policies for AWS Partner Central users](https://docs.aws.amazon.com/partner-central/latest/getting-started/managed-policies.html) for the full role-to-policy mapping. 3. If the user's role assignment looks correct but access still isn't working, refer to [Controlling access in AWS Partner Central](https://docs.aws.amazon.com/partner-central/latest/getting-started/controlling-access-in-aws-partner-central.html) for further troubleshooting guidance. ## Frequently asked questions **Will migration impact AWS Marketplace activity?** No. Marketplace accounts remain linked. The migration consolidates access into the new Partner Central experience. **Will this affect Fours or other integrations?** No. IAM permission updates don't impact Fours functionality. **Why can't some users access Partner Central after migration?** See [Part C: Troubleshoot access issues](#part-c-troubleshoot-access-issues) for detailed guidance on what to do. --- Source: https://doc.fours.com/aws-marketplace/china-marketplace/ # AWS China Marketplace ## Overview AWS China Marketplace is a localized version of AWS Marketplace for mainland China, operated separately by local AWS China partners (Ningxia and Beijing regions). It lets you sell your SaaS products to customers in the China region. ## Connecting AWS China Marketplace connects at the **organization level**, following the same flow as the main [AWS Marketplace integration](/aws-marketplace/integration) — connect from the Fours console and grant Fours access to your AWS China seller account. ### Prerequisites - An AWS China Marketplace seller account - An AWS China (`cn-north-1` / `cn-northwest-1`) account with marketplace access - Localized business credentials required for China-region operations :::note AWS China is operated independently from AWS global. Use your AWS China seller account and China-region credentials when connecting. ::: --- Source: https://doc.fours.com/aws-marketplace/support-cases/ # AWS Support Cases Open AWS support cases and follow up on AWS's replies from the Fours Console, without switching to the AWS Support Center. --- ## Overview Once you connect the AWS Support integration, Fours can talk to the AWS Support API on your behalf. From the Fours Console you can: - **Open a case** with AWS — pick the service and category, set a severity, and write the subject and description. - **Open a case in context** — start a pre-filled case directly from an AWS offer, entitlement, or product. - **Attach files** — add up to 3 files, 5 MB each, to a new case or to a reply. - **CC colleagues** — copy up to 10 email addresses on the case correspondence. - **Read the correspondence** — the messages AWS and your team have exchanged on the case. - **Reply to AWS** — add a message to an existing case. :::info What this page is not about The **Support Tickets** tab on the same page is Fours' own ticketing system for reaching the Fours team, and it is a different feature with different capabilities (comments, attachments, close and reopen) — see [Support Tickets](/console/support-tickets/). This page covers only the **AWS Support** tab, which talks to AWS. ::: ### What the console does not do yet | Not available in Fours | Where to do it instead | | ---------------------- | ---------------------- | | Resolving, closing, or reopening a case | [AWS Support Center](https://console.aws.amazon.com/support/home) | Cases you open through Fours are ordinary AWS support cases, so they are also visible and fully manageable in the AWS Support Center under the same AWS account. --- ## Prerequisites ### An eligible AWS Support plan The AWS Support API is only available on **Business**, **Enterprise On-Ramp**, and **Enterprise** Support plans. On a Basic or Developer plan the integration cannot be verified, and Fours reports: > AWS account does not have a Business, Enterprise On-Ramp, or Enterprise Support plan required to use the AWS Support API ### Fours permissions | Fours role | Connect or edit the integration | Read cases | Open a case | Reply to a case | | ---------- | ------------------------------- | ---------- | ----------- | --------------- | | Admin | Yes | Yes | Yes | Yes | | Editor | No | Yes | Yes | Yes | | Viewer | No | Yes | No | No | Cases are visible to your whole organization, not only to the person who opened them — anyone with read access sees the same list and the same correspondence. ### Connect the AWS Support integration The integration is separate from your AWS Marketplace integration — connecting AWS Marketplace does not grant Fours access to the AWS Support API. You grant that access with an IAM role that Fours assumes. Connecting it requires the Fours **Admin** role. 1. In the [Fours Console](https://console.suger.io/settings?tab=integrations), go to **Settings** → **Integrations** and find the **AWS Support** card. 2. Click **Connect**. The **Connect to AWS Support** dialog shows everything you need to create the role: your **External ID**, a **Permissions policy**, and a **Trust relationship**. ![Connect to AWS Support dialog in Fours, showing the external ID and the permissions policy to copy](images/aws-support-cases-1.png) 3. In the AWS IAM console, create a role in the AWS account that holds your Support plan. Any role name works; the dialog's example uses `SugerAwsSupportAccess`. Paste the **Permissions policy** as an inline policy and the **Trust relationship** as the role's trust policy, copying both from the dialog. The permissions policy grants exactly the AWS Support API actions Fours uses, and nothing more: | Action | Used for | | ------ | -------- | | `support:DescribeServices` | The service and category pickers on the create form | | `support:DescribeSeverityLevels` | The severity picker, and the integration's Verify check | | `support:CreateCase` | Opening a case | | `support:DescribeCases` | Refreshing a case's status | | `support:DescribeCommunications` | Reading the correspondence on a case | | `support:AddCommunicationToCase` | Replying to a case | | `support:AddAttachmentsToSet` | Uploading file attachments on a case or a reply | :::warning Already connected? Re-apply the policy for attachments `support:AddAttachmentsToSet` was added to the policy when attachment support shipped. A role created before then does not have it, and attachment uploads are denied until you re-apply the policy — everything else on the integration keeps working, so the gap only shows up the first time someone attaches a file. Copy the current **Permissions policy** from the **AWS Support** integration card and paste it over the role's inline policy. If the role or its trust policy also changed, reconnect the integration instead. ::: :::info Copy the trust policy from the dialog The trust policy names the Fours AWS account that assumes the role and pins the **External ID** to your organization. Both values differ per Fours environment, so always copy the block shown in your dialog rather than reusing one from elsewhere. ::: 4. Copy the new role's ARN, paste it into **IAM Role ARN**, and click **Create**. The ARN must be a commercial-partition IAM role ARN in the form `arn:aws:iam:::role/`; AWS China (`aws-cn`) and GovCloud (`aws-us-gov`) ARNs are rejected. 5. Fours verifies the connection by assuming the role and calling the Support API. Once the card shows the integration as verified, the **AWS Support** tab is ready. ![AWS Support integration card in Settings, showing a verified connection](images/aws-support-cases-2.png) :::warning One integration per organization An organization can have a single AWS Support integration. You can update its **IAM Role ARN** later from the card's **⋯** menu → **Edit**, but the ARN must stay in the same AWS account — to point Fours at a different AWS account, delete the integration and connect again. Cases opened under the previous account stay in the list but can no longer be opened or replied to. ::: --- ## Open a support case 1. In the [Fours Console](https://console.suger.io/support), click the **help** icon in the top bar to reach the Support page, then select the **AWS Support** tab. 2. Click **Open AWS Support Case**. ![AWS Support tab with the Open AWS Support Case button](images/aws-support-cases-3.png) 3. Fill in the case. The first five fields are required; **Attachments** and **CC** are optional: - **Subject** — a short summary, up to 300 characters. - **Service** — the AWS service the case is about. The list is read live from your AWS account, so it matches what the AWS Support Center offers. Fours preselects **AWS Marketplace**, because that is what most cases opened through Fours are about — change it if your case is about something else. - **Category** — the case category. The options depend on the service, so pick the service first. - **Severity** — the severity levels your Support plan entitles you to, shown as name and code. Fours preselects the first level in the list. - **Description** — the details AWS needs, up to 8,000 characters. - **Attachments** — up to **3 files**, **5 MB each**. Click **Attach files** to pick them; files beyond either limit are dropped with a message saying why. - **CC** — up to **10 email addresses** to copy on the case correspondence. Over the limit, the field reports "At most 10 cc addresses are allowed." ![Open AWS Support Case dialog with all fields filled in](images/aws-support-cases-4.png) 4. Click **Open Case**. Fours creates the case in AWS and it appears in the list with its AWS **Case ID**. Both limits are enforced by Fours' API as well as by the form, so a case created through the Fours API is held to the same 3 files, 5 MB each, and 10 CC addresses. ### Find a service quickly The service list is long, so the **Service** picker has a search box. The search is case-insensitive and matches on both the service name and its service code: - Type any fragment that appears in the name or the code — `ec2` finds every Elastic Compute Cloud entry. - Type several words in any order and each one has to appear somewhere — `linux ec2` narrows to the Linux-specific EC2 entry. - Clear the box to get the full list back. ![Service picker with a search term entered and matching services listed](images/aws-support-cases-5.png) ### Open a case from an offer, entitlement, or product When a case is about a specific record, start it from that record so the case is linked and pre-filled: 1. Open an AWS offer, entitlement, or product detail page. 2. In the **⋯** menu, click **Create AWS Support Case**. 3. The dialog opens with the record's identifiers already in the subject and description, and a banner naming the linked record. Adjust the text, pick the service, category, and severity, then click **Open Case**. From an offer, the subject arrives as `AWS Support — Offer `. AWS caps a case subject at 300 bytes, so a long offer name is truncated to fit rather than being rejected on submit. You can edit the prefilled subject before you send it. The menu item appears only on AWS records, only once the AWS Support integration is verified, and only for users who can open cases — Viewers don't see it. --- ## Track and reply to a case The **AWS Support** tab lists every case your organization has opened through Fours, newest first, with its **Case ID**, **Subject**, **Status**, **Opened** date, and **Last Update**. Click a **Case ID** to open the case. Fours fetches the current status and the correspondence from AWS, then shows the messages oldest-first, each with its author and timestamp. ![AWS support case detail, showing the correspondence thread and the reply box](images/aws-support-cases-6.png) To respond, type in the reply box and click **Send Reply** — up to 8,000 characters. A reply takes the same **Attachments** (up to 3 files, 5 MB each) and **CC** (up to 10 addresses) as a new case. AWS adds your message to the case correspondence, exactly as if you had replied in the AWS Support Center. Admins and Editors can reply; Viewers can only read. ### Who sent each message Every message in the thread is labeled with its sender: | Message | Shown as | | ------- | -------- | | Sent from Fours | The email address of the person who sent it | | Sent from Fours before per-user attribution shipped | `Suger` | | Sent by an AWS support agent | Whatever AWS reports, unchanged | Because AWS records the case against the IAM role Fours assumes, older messages cannot be attributed to an individual after the fact — they keep the generic `Suger` label. New messages carry the sender's email from the moment they are posted. :::info Statuses refresh when you open a case **Status** comes from AWS, and Fours refreshes it when you open the case — not on a timer. If AWS has worked the case since you last opened it, the list keeps showing the older status until you open the case again. The correspondence itself is always fetched live, so opening a case shows you the current thread. ::: --- ## Use AWS Support in the new console If your team works in the new console — the desktop you [switch to](/insulin/getting-started/#switching-between-the-classic-console-and-insulin) with the **insulin** wordmark in the console top bar — AWS Support is also an app there. It is the same feature, not a second integration: the same verified AWS Support integration, the same AWS account, and the same cases, so a case opened in one view appears in the other, and in the AWS Support Center. **AWS Support is not pinned to the Dock.** Open it from the **Search apps…** launcher in the System Bar — click it, or press **Cmd/Ctrl + Space** — then type *AWS Support*. Until your organization has a verified AWS Support integration, the app shows **AWS Support is not connected** and names the support plans it requires. Connect it as described in [Connect the AWS Support integration](#connect-the-aws-support-integration). ![The AWS Support app before the integration is connected — the message naming the required AWS support plan](images/aws-support-cases-not-connected.png) The case list, the create form, and the reply thread work as described above, with four differences: - **The create button is labeled Open Case**, at the top right of the window. - **The controls follow your permissions.** Opening a case and replying are permissioned separately, so a role that can read cases but not open them sees no **Open Case** button, and one that cannot reply sees no reply box — rather than hitting a permission error after filling in a form. - **The Service, Category, and Severity lists load live from your AWS account.** If they fail to load, the dialog says so and offers **Retry**; the form cannot be submitted until they load, because a case needs a real service and category code. - **A case opened from an offer shows the offer's name** in its header, with the identifier on the line beneath it, so a case titled after an offer ID is still readable months later. --- ## FAQ ### The AWS Support tab says the integration is not connected. What now? The tab needs a *verified* AWS Support integration, which is separate from your AWS Marketplace integration. Follow [Connect the AWS Support integration](#connect-the-aws-support-integration). If you just created it and verification failed, confirm the AWS account has a Business, Enterprise On-Ramp, or Enterprise Support plan. ### The service dropdown is empty or shows an error. Fours reads the service catalog live from AWS through the assumed role. If it can't, check that the IAM role still exists, that its trust policy is unchanged, and that the permissions policy includes `support:DescribeServices`. Fours tells you when it can no longer assume the role — reconnect the integration in that case. ### Why can't I see all the severity levels AWS documents? The list is read from your AWS account, so it shows exactly the levels your Support plan entitles you to — higher plans include more levels. ### Can I attach a file or CC a colleague? Yes, on both a new case and a reply. Attachments are limited to **3 files of 5 MB each**, and **CC** takes up to **10 email addresses** — AWS's own limits, which Fours enforces before calling AWS so you get a clear message instead of a raw AWS validation error. ### My attachment upload was denied. Why? The IAM role Fours assumes needs `support:AddAttachmentsToSet`, which was added to the permissions policy when attachments shipped. A role created before then lacks it. Re-apply the current **Permissions policy** from the **AWS Support** integration card to the role — see [Connect the AWS Support integration](#connect-the-aws-support-integration). ### How do I resolve or close a case? Close it in the AWS Support Center. Fours shows the resolved status the next time you open the case. ### Why doesn't my case appear right after I click Open Case? A case shows up once AWS has accepted it and returned a case ID. If it doesn't appear, check the error message on the dialog — AWS rejects requests that exceed its case-creation limit or fail its own validation, and Fours passes that message through. ### Is this the same as a Fours support ticket? No. The **Support Tickets** tab reaches the Fours team; the **AWS Support** tab reaches AWS. For questions about Fours itself, use [Support Tickets](/console/support-tickets/) or email [Fours Support](mailto:support@suger.io). --- ## Related Documentation - [AWS Marketplace Integration](/aws-marketplace/integration/) - [Refunds and Cancellations](/aws-marketplace/refunds-cancellations/) - [AWS Support Center](https://console.aws.amazon.com/support/home) — the AWS-side view of the same cases - [AWS Support API reference](https://docs.aws.amazon.com/awssupport/latest/APIReference/Welcome.html) --- Source: https://doc.fours.com/aws-marketplace/pre-authorized-auto-renewal/ # Pre-Authorized Auto-Renewal Let an AWS agreement renew on terms the buyer already agreed to, instead of negotiating a new private offer each cycle. --- ## Overview **Pre-authorized auto-renewal (PAR) is a renewal term carried on the private offer itself.** The buyer accepts the renewal rules once, when they accept the offer; AWS then renews the agreement on those rules without a new offer, a new acceptance, or a new signature. There are two halves, and they live in different places: | | Where | Who | | --- | ----- | --- | | **Configure the terms** | The offer form, before the buyer accepts. Terms are fixed at acceptance. | Seller | | **Manage the renewal** | The **Renewal** section on the entitlement, after the buyer accepts. | Seller | Renewal terms can be configured from the Fours Console, the [Fours Salesforce app](/salesforce-app/salesforce-app-offer/) and the [Fours HubSpot app](/hubspot-app/hubspot-app-offer/). ## Which offers can carry renewal terms The **Configure renewal terms** section appears only on an eligible offer. It is not a setting you can switch on — eligibility is decided by the offer itself: | Requirement | Detail | | ----------- | ------ | | **Offer type** | `CONTRACT`, `PROFESSIONAL_SERVICES`, or `CONTAINER`. | | **Not an AMI product** | AWS offers no auto-renewal for AMI products, so an AMI offer never shows the section. | | **Has commits** | The offer must carry at least one committed dimension. | | **Not a resale authorization** | CPPO offers are excluded. | | **Not agreement-based** | An offer created from an existing agreement is excluded. | :::note Usage dimensions do not disqualify an offer: an offer that carries committed **and** usage dimensions still shows the section. Whether AWS accepts a renewal term for the offer's pricing model is AWS's decision, made when the offer is created. If AWS refuses it, the create fails with *"AWS does not support a renewal term for this offer's pricing model. Create this offer again without the pre-authorized renewal term."* ::: ## Configure renewal terms ### Renewal option Pick one: | Option | What it means | | ------ | ------------- | | **No price uplift** | Renew at the same price each cycle. | | **Price uplift** | Increase pricing by a fixed percentage, or within a pre-negotiated range, each cycle. | | **No renewal** | Do not include auto-renewal terms with this offer. | ### Price uplift type **Price uplift** asks for one of two shapes: | Uplift type | Fields | Rules | | ----------- | ------ | ----- | | **Fixed percentage** | **Price increase percentage** | 0–100, at most two decimal places. | | **Percentage range** | **Minimum**, **Maximum** and **Default** uplift percentage | Each 0–100. **Minimum must be less than Maximum**, and **Default must fall inside the range**. | A **percentage range** is what makes the renewal adjustable later: it is the pre-negotiated band the seller may move the final figure within before each renewal. A **fixed percentage** has nothing to adjust. In the Fours Console, choosing **Percentage range** pre-fills a 5%–30% band with a 10% default, which you can change. If no value is finalized before the adjustment deadline, the default is charged automatically at renewal — and it compounds on the previous cycle's price. ### Renewal decision deadline and adjustment deadline Both are a number of days measured back from the agreement's end date, and both bound *when* the seller may still act: | Field | What it bounds | Constraint | | ----- | -------------- | ---------- | | **Renewal decision deadline** (optional) | The lockout period: after this point neither party can opt out of the renewal. | Opens empty. Left blank, AWS uses its own default, the agreement expiration date. If you set it, it must be **greater than zero** and **shorter than the contract duration**. | | **Adjustment deadline** | After this point the uplift percentage can no longer be changed. | **Required** for a percentage range, and must be **greater than the renewal decision deadline**. Choosing **Percentage range** pre-fills it with the renewal decision deadline plus 30 days — or 30 days when that field is blank. | Because the adjustment deadline is more days before the end date, it falls *earlier* on the calendar than the renewal decision deadline. That is the point of the pair: the uplift is settled first, while either side can still decide not to renew. The contract duration these fields are checked against is the offer's own term — its typed length, or the span between its start and end dates when you set the term by dates. ### Renewal count **Renewal count** is either **Definite** — a specific number of renewals, at least 1 — or **Indefinite**, which renews until someone stops it. ### Renewal payment schedule An offer with installments can carry a renewal payment schedule, so each renewed term is invoiced on the same rhythm as the first: - At most **86** installment entries. - Each entry's **% of total** is between **0.01 and 100**, with at most two decimal places. - The entries must **total exactly 100%**. A schedule that totals 99.99% is rejected rather than rounded. - Every entry must fall **within the contract's duration** — AWS rejects one that doesn't ([AWS Marketplace developer guide](https://docs.aws.amazon.com/marketplace/latest/developerguide/work-with-private-offers.html)) — so on a 12-month term the entries run from month 0 to month 11. In the Fours Console, the section opens only when the offer actually has installments; a single-payment offer has no schedule to renew. **The schedule starts from the offer's own installments.** In the Fours Console, when the section opens, each installment of the offer becomes an entry carrying its share of the total, timed from the start of the agreement. The offer's start date — set when you enable a future start date — begins month 0, and each month runs from that day of the month: with an October 15 start, a November 1 installment is still in month 0, so twelve monthly installments from November 1 run from month 0 to month 11. When the offer has no start date, or an installment falls before it, the earliest installment is month 0 and later entries count calendar months from it. Entries are timed in months; if two installments land in the same month, the whole schedule is timed in exact days instead, and installments on the same date become one entry. While you are still changing the offer's installments, the schedule follows them. Once you edit the schedule itself, your entries are kept as you left them — and an offer you reopen with a saved renewal schedule keeps that schedule. In the Fours Console, one unit applies to the whole schedule. Choose **By month** or **By exact days** beside the **Renewal Payment Scheduler** button, which generates up to 86 equal installments; the column heading reads **Months after agreement start** or **Days after agreement start** to match. When the offer's installments carry amounts, the schedule also shows: - **Original contract total** and **Contract duration** above the entries — the figures the entries are measured against. - An **Estimated first renewal cycle payment amount** on every entry, in the offer's currency: the entry's share of the contract total after one cycle of uplift. **The billing day, and the last month's exception.** On a schedule timed **By month**, each entry can also take an optional **Day of month** (1–31) to bill on. The exception is the entry in the contract's last month — on a 12-month term, the one 11 months after agreement start. AWS bills that entry on the same day of the month the renewal starts and refuses a custom day on it, so its **Day of month** reads **Start day** and can't be changed. The tooltip beside it says *"AWS bills the last installment on the same day of the month the renewal starts. A custom day isn't allowed for the last month."*, and the scheduler's **Day of month** field notes *"Optional. The last month always bills on the renewal start day."* A schedule built from the offer's installments leaves that entry's day off too. A schedule timed **By exact days** has no billing day at all. The Fours Salesforce and HubSpot apps lock the same entry. **No entry after the last month.** On a schedule timed **By month** whose contract term is set in months or years, Fours checks the entries against the term itself rather than leaving it to AWS. An entry after the term's last month — 24 monthly installments generated on a 12-month term, say — makes Fours refuse the offer when you click **Create offer**, and the *Failed to create offer* message includes the entry's offset, for example *AWS renewal schedule entry "P12M" is past the last month of the renewal agreement (a term of this length has offsets P0M to P11M)*. Move the entry into the term, or rebuild the schedule with fewer installments, and create the offer again. ## Manage the renewal after acceptance Once the buyer accepts, the terms are on the agreement and the entitlement grows a **Renewal** section with two tabs. ### Renewal details | Field | What it tells you | | ----- | ----------------- | | **Renewal status** | Whether the agreement is set to renew. | | **Renewal pricing** | The uplift shape that was agreed — none, fixed, or a range. | | **Price uplift range** | The pre-negotiated minimum and maximum, on a range term. | | **Default uplift percentage** | Where inside the range the uplift sits if nobody adjusts it. | | **Uplift status** | Whether the uplift for the next renewal is settled: **Pending uplift** on a percentage-range term until it is finalized; **Finalized** with the date once you publish it or AWS finalizes it at the adjustment deadline; plain **Finalized** for a fixed-percentage or no-uplift term, which has nothing to adjust. | | **Renewal count** | Definite (with the number) or Indefinite. | | **Lockout date** | The date after which opting out is no longer possible. **N/A** when the offer left the renewal decision deadline blank — AWS then uses the agreement expiration date. | | **Adjustment deadline** | The date after which the uplift can no longer be changed. | | **Next renewal date** | When the next term begins. | | **Renewal disabled reason** | Shown only when the agreement will *not* renew, and says why. | When the offer carried one, a **Renewal payment schedule** table follows: contract duration, number of installments, and a row per installment with its payment timing and **% of total**. ### Renewal history The **Renewal history** tab lists the chain of agreements — each renewal produced its own agreement ID, and the previous agreement is named. When Fours has not yet read a predecessor in the chain, the tab says **Predecessor pending** rather than showing a broken chain. ### Adjust uplift % Sets the uplift for the next renewal inside the pre-negotiated range. Offered only when **all** of these hold: - the term is a **percentage range** — a no-uplift or fixed-percentage term has nothing to adjust; - the agreement has **not yet passed its adjustment deadline**; - the uplift has **not been finalized** yet — once it is, the action disappears; - the entitlement is live, has no pending cancellation, and has not been opted out of auto-renewal. **Adjust uplift %** opens the **Adjust renewal uplift** dialog. Its summary shows the agreed **Uplift range**, the **Default uplift** and the **Adjustment deadline**, and the tables below it preview each line's price at the next renewal. The prices are a preview; Fours computes the final amounts and AWS validates them. - **Target uplift percentage** — one flat uplift for the renewal. - **Set an uplift per dimension** — price lines individually instead. Each line starts at the range default; change any line to price it differently. - On an offer **without installments**, the switch covers every contract and usage dimension and replaces the flat uplift. - On an offer **with installments**, the **Target uplift percentage** always prices the payment schedule, and the switch applies to usage dimensions only. With it off, usage takes its own **Usage uplift percentage**. Every value must stay within the agreed range; the dialog flags one that doesn't (*"Uplift must be between …% and …%."*). Then choose how to submit: | Action | What happens | | ------ | ------------ | | **Save as draft** | Saves the repriced renewal offer without releasing it to the buyer. The status stays **Pending uplift**, and reopening the dialog picks up the saved values. | | **Publish** | Asks you to confirm — *"Publishing releases this renewal offer to the buyer and notifies them immediately. This action is irreversible."* — then releases it. The status becomes **Finalized** with the date, and **Adjust uplift %** is no longer offered. | ```d2 direction: down accepted: "Buyer accepts an offer\nwith a percentage-range term" pending: "Uplift status: Pending uplift" draft: "Saved draft\nrepriced, not released to the buyer\n(status stays Pending uplift)" reminder: "Reminder notification\nonce per renewal cycle,\nfrom 30 days before the deadline" finalized: "Uplift status: Finalized, with the date" accepted -> pending pending -> draft: "Adjust uplift %, Save as draft" pending -> finalized: "Adjust uplift %, Publish\n(irreversible; releases the renewal offer)" draft -> finalized: "Publish" pending -> finalized: "Adjustment deadline passes:\nAWS finalizes at the default uplift" pending -> reminder: "while not finalized" { style.stroke-dash: 4 } ``` ### Opt out of auto-renewal Stops the agreement renewing. Unlike the uplift adjustment this applies to **any** renewal term — stopping a renewal is independent of how it was priced — but it must happen **before the lockout date**. :::warning **Opting out is not reversible from Fours.** Once the renewal is off, restoring it means a new offer. ::: ### Both take effect asynchronously AWS propagates a renewal change on its own schedule, so neither action is reflected the moment you confirm it. Give it a few minutes and refresh the entitlement; the **Renewal details** tab shows the state AWS has actually recorded, not what was requested. ### Reminder before the adjustment deadline So a percentage-range uplift is not left to the default by accident, Fours reminds you while it is still **Pending uplift**. A daily check sends one reminder per entitlement cycle, beginning 30 days before the deadline. It uses the entitlement notification scope `RENEW_UPLIFT_PENDING.ENTITLEMENT`: the email's subject reads *"Action needed: finalize your renewal price uplift"* followed by the entitlement name, and Slack or Microsoft Teams receive it too if you route that scope there. Once the uplift is finalized, no reminder is sent. The email goes out only when **Enable Email Notification** is on for your organization and the scope's row is enabled with recipients — see [Email Notification](/settings/email-notification/). ## What the buyer sees The renewal produces a **new agreement**, not an extension of the old one. The buyer's original agreement ends on its end date and the renewed agreement starts alongside it — which is why a renewed customer has more than one agreement in their AWS console, and why the entitlement list shows a new entitlement rather than a moved end date. See [Accept Private Offer](/aws-marketplace/accept-private-offer/). ## Related - [Create a Private Offer](/aws-marketplace/create-private-offer/) - [Accept Private Offer](/aws-marketplace/accept-private-offer/) - [Private Offers in the Salesforce app](/salesforce-app/salesforce-app-offer/) - [AWS Marketplace Integration](/aws-marketplace/integration/) --- Source: https://doc.fours.com/aws-marketplace/ # AWS Marketplace AWS Marketplace is the broadest channel Fours supports, and the one with the most decisions to make before you write a word of your listing. You choose a product type, then a pricing model that AWS locks once the listing is published, and AWS reviews the finished listing — including a walkthrough of your buyer experience — before anyone can buy. A net-new listing takes about three weeks end to end, roughly two of which are AWS's review; moving a listing you already have onto Fours takes about five days. You connect once, by launching a CloudFormation stack that creates an IAM role Fours uses to act on your AWS Marketplace seller account. From then on, listings, private offers, reseller authorizations, metering, refunds, and even AWS support cases run from the Fours Console rather than the AWS Marketplace Management Portal. ## Get your product listed Work through these in order the first time. 1. **[Self-Serve Onboarding Guide](/aws-marketplace/self-serve-onboarding/)** — the whole journey in phases, starting from AWS seller registration, tax, and bank details before Fours is involved at all. 2. **[Integration](/aws-marketplace/integration/)** — run the CloudFormation stack that grants Fours access, and enable EventBridge so a single buyer can hold several concurrent agreements. 3. **[Product Types](/aws-marketplace/product-types/)** — SaaS and professional services are built directly in Fours; AMI and container products must be created in AWS first and then sync in; machine learning products are not supported. 4. **[Pricing Model](/aws-marketplace/pricing-model/)** — compare subscription, contract, contract-with-subscription, and free, and understand why the choice cannot be changed once the listing is published to Limited. 5. **[List Product](/aws-marketplace/list-product/)** — build the listing, fulfillment, and pricing that become one AWS Marketplace product. 6. **[Submit Your Listing for Approval](/aws-marketplace/submit-listing/)** — the final implementation checklist and the buyer-experience demo video AWS reviewers ask for. ## Close a deal with a private offer - **[Create Private Offer](/aws-marketplace/create-private-offer/)** — build subscription, contract, combined, agreement-based, professional services, container, AMI, and free-trial offers, and see which support commits, installments, or multiple currencies. - **[Private Offer Best Practices](/aws-marketplace/offer-best-practices/)** — what to collect before you start, and the eligibility, expiry, and start-date rules that most often derail an offer. - **[Sync Dimensions to Private Offers](/aws-marketplace/dimension-sync/)** — add a newly-listed usage dimension to offers you already released, in bulk, without touching their existing prices. - **[Channel Partner Private Offers (CPPO)](/aws-marketplace/cppo/)** — authorize a reseller at wholesale pricing and track the resale opportunity, the partner's offer, and the resulting entitlement in one place. - **[Accept Private Offer](/aws-marketplace/accept-private-offer/)** — the buyer's side of the transaction, useful when a customer asks what they will see and which AWS permissions they need. ## Keep a live listing current - **[Update Listing](/aws-marketplace/update-listing/)** — edit, republish, restrict, or clone a published listing, and see what each AWS listing status still lets you change. - **[Buy with AWS](/aws-marketplace/buy-with-aws/)** — put the AWS purchase flow on your own pricing page, currently for SaaS listings with subscription pricing. - **[Deployed on AWS Badge](/aws-marketplace/deployed-on-aws-badge/)** — what the badge signals to buyers, and how to submit your architecture for AWS review. ## Track the money - **[Revenue](/aws-marketplace/revenue/)** — how Fours turns the AWS Marketplace Data Feed into revenue records, and what each invoiced, collected, disbursed, and forgiven amount means. - **[Finance, Billing, and Tax](/aws-marketplace/finance-billing/)** — the workflow for your finance team: which console pages to live in, disbursement settings, event notifications, and tax. - **[Refunds and Cancellations](/aws-marketplace/refunds-cancellations/)** — request a refund or cancel an agreement from the Entitlements page instead of filing an AWS support ticket. ## Sell in specialized AWS channels - **[Bedrock Managed Entitlements](/aws-marketplace/bedrock-managed-entitlements/)** — extend the contracted price from a Bedrock model private offer to every member account in the buyer's AWS Organization, instead of just the payer account. - **[AWS China Marketplace](/aws-marketplace/china-marketplace/)** — sell SaaS to mainland China through the separately operated Ningxia and Beijing marketplace, using a distinct China seller account. ## Work with AWS itself - **[Migrate to AWS Partner Central 3.0](/aws-marketplace/migrate-to-aws-partner-central/)** — move your team's Partner Central access into the AWS Console; this changes how people sign in, not how ACE data syncs to Fours. - **[AWS Support Cases](/aws-marketplace/support-cases/)** — open an AWS case, read AWS's replies, and respond, from the same console you manage offers in. ## Scope and limits :::info Fours creates SaaS and professional services listings directly. AMI and container products must be created in AWS Marketplace first and then sync into Fours; machine learning products are not supported. Tax is AWS's job as well as the money: AWS invoices your buyers, then nets both its marketplace fee and tax before disbursing to your bank. Fours performs neither the payment nor the tax calculation — it reads the AWS Marketplace Data Feed delivered to your seller S3 bucket and normalizes it into revenue records. Starting **June 1, 2026**, AWS requires concurrent agreements support for all new SaaS products, which makes the EventBridge part of the integration step above mandatory for new listings rather than optional. ::: --- Source: https://doc.fours.com/azure-marketplace/self-serve-onboarding/ # Self Serve Onboarding Guide Everything you need to go live on Microsoft Azure Marketplace with Fours, step by step, at your own pace. --- :::info New to cloud marketplaces? See [What Is a Cloud Marketplace](/concepts/what-is-cloud-marketplace/) for the basics before diving in. ::: ## What to expect This is a self-serve guide — no need to wait for a meeting to get started. Azure's process is similar in timeline to AWS: most of the wait is Microsoft's review period, not your work time. The full journey from account setup to your first private offer typically takes **3-4 weeks**, with your actual hands-on time commitment roughly **3-4 hours** spread across the process. Use your dedicated Slack channel for questions at any point, or email [support@suger.io](mailto:support@suger.io) for urgent issues. ```d2 direction: down p0: "Phase 0 — Azure setup\nPartner Center account,\npublisher profile\nDay 1-2" p1: "Phase 1 — Account setup\nFours org approved,\nAzure integration connected\nDay 1" p2: "Phase 2 — Create your listing\nBuild & submit for\nMicrosoft review\nDay 2-3" p3: "Phase 3 — Go live & test\nConfirm listing,\nsend a test private offer\nWeek 3-4" optional: "Optional — anytime after Phase 1" { p4: "Phase 4 — CRM integration\nSalesforce or HubSpot" p5: "Phase 5 — Co-Sell setup\nAzure Co-Sell" } p0 -> p1 -> p2 -> p3 p1 -> optional { style.stroke-dash: 4 } ``` | Phase | What you're doing | Est. time | | --- | --- | --- | | 0 — Azure setup | Partner Center account, publisher profile | Day 1-2 | | 1 — Account setup | Create & get approved on the Fours console, connect Azure integration | Day 1 | | 2 — Create your listing | Build and submit product listing for Azure review | Day 2-3 | | 3 — Go live & test | Confirm listing, send test private offer | Week 3-4 (after Azure review) | | 4 — CRM integration | Connect Salesforce or HubSpot | Anytime after Phase 1 | | 5 — Co-Sell setup | Connect Azure Co-Sell | Anytime after Phase 1 | Work through Phases 0-5 in order — Phases 4 and 5 are optional, skip them if they don't apply to you. ## Before you start - **Your business** — a registered legal business entity, a company email address, and enrollment in the **Microsoft AI Cloud Partner Program** (formerly the Microsoft Partner Network) with a verified Partner ID — free to set up at [partner.microsoft.com](https://partner.microsoft.com) if you haven't already. - **A Microsoft account and Azure subscription** — active, with billing enabled. - **Someone with Global Administrator access** — in both your Azure tenant and Microsoft Partner Center. Connecting Azure to Fours in Phase 1 requires this specific role; a lower-privileged admin role typically can't grant the required consent and will block the integration. - **Your product** — a live, publicly accessible fulfillment URL, plus a support email, support URL, and privacy policy URL (Microsoft requires all three for listing approval). - **A logo** — a company or product logo in PNG format. Bank account details and tax forms can be set up as you go through Phase 0. ## Phase 0: Set up Azure Marketplace Before you can create marketplace listings, register as a Microsoft marketplace publisher. **Estimated time:** ~1 hour of hands-on work. Bank account verification may take a few additional business days. ### Set up your Microsoft Partner Center account Partner Center is Microsoft's hub for marketplace publishers — you'll create your publisher profile here, accept the Microsoft Publisher Agreement, and set up your payout account. Have a live support URL and privacy policy URL ready (Microsoft checks both, and requires the privacy policy to stay live permanently), plus bank account details and tax forms for your payout account (set this up early — verification takes a few days). See Microsoft's [Create a Microsoft Marketplace account in Partner Center](https://learn.microsoft.com/en-us/partner-center/account-settings/create-account). :::tip **Phase 0 complete when:** your Microsoft Partner Center account and publisher profile are set up. ::: ## Phase 1: Account setup & connect to Fours Before you can create listings, you'll need a Fours organization, access to the Fours Console, and your Azure Marketplace account connected to Fours. **Estimated time:** ~10 minutes of hands-on work, plus up to 1 business day for organization approval. 1. Go to [console.suger.io](https://console.suger.io) and sign up using your company email domain (not a personal email). 2. Your organization stays in a **Pending Approval** state until the Fours team approves it — send a quick message in your shared Slack channel once you've created it so we can process the approval. Once approved, you'll get a confirmation email. Approval typically takes up to 1 business day; if you haven't heard back after that, reach out again in your Slack channel. 3. Once approved, invite the teammates who will participate in the implementation — see [Invite Your Team](/get-started/account/#invite-your-team). 4. Connect Azure Marketplace to Fours. This links your Partner Center account to the Fours console. It requires **Global Administrator** access in both your Azure tenant and Partner Center (a narrower admin role typically can't grant the required consent), and takes about 30-60 minutes end to end — including the eligibility checklist, enrolling in the required Partner Programs, and completing the connect flow in the Fours Console. See [Integrate Azure Marketplace with Fours](/azure-marketplace/integration/). :::tip **Phase 1 complete when:** your org is approved, your team is added to the console, and your Azure integration shows as connected in the Fours console. ::: ## Phase 2: Create your product listing In this phase, you'll create your Azure Marketplace listing in Fours and submit it to Microsoft for review — this is the listing customers will see when they discover your product in Azure Marketplace. **Estimated time:** ~1-2 hours of hands-on work, plus ~2 weeks for Microsoft's review. In the Fours console, go to **Products → Create Product**, select Azure, and follow the prompts — Fours uses AI-assisted templates to pre-fill a lot of the content, so use these as a starting point and refine from there. See [Create and Publish an Azure Marketplace Listing](/azure-marketplace/list-product/). Once your listing looks good, Fours submits it to Microsoft on your behalf. Microsoft follows up via the email on your Partner Center account if anything needs to change during review. If you have an active deal waiting on your listing, let your Fours contact know — listings can be expedited in that case. :::tip **Phase 2 complete when:** your listing has been submitted and Microsoft has confirmed it's under review. ::: ## Phase 3: Go live & test with a private offer Once your listing is approved, confirm it's live and validate the buyer experience end to end before working with real customers. **Estimated time:** Less than 1 hour once your listing has been approved. 1. In the Fours Console, go to **Product**, open your Azure product, and confirm the status is **Public**. You can also confirm the listing is live directly in [Partner Center](https://partner.microsoft.com/en-us/dashboard/marketplace-offers/overview). 2. Create and accept a private offer using an account you control, to verify your private offer workflow, fulfillment, and entitlement processing all work before inviting real customers. See [Create an Azure Marketplace Private Offer](/azure-marketplace/create-private-offer/). Don't skip this step — it's much easier to catch issues here than after a real customer transacts. :::tip **Phase 3 complete when:** your test offer has been sent, accepted, and confirmed in Fours. You're ready for real buyers. ::: ## Phase 4: CRM integration (optional) If your team uses Salesforce or HubSpot, connect it to Fours to manage private offers and co-sell opportunities more efficiently. Skip this phase if you use neither — check with your Fours contact if you're unsure whether CRM integration is included in your subscription. - Salesforce (~1 hour, requires a Salesforce Admin) — lets your sales team send private offers and share opportunities without leaving Salesforce. See [Integrate Salesforce with Fours](/integrations/salesforce/#overview). - HubSpot (~10 minutes, requires access to install apps and grant CRM permissions in HubSpot) — enables co-sell capabilities from the Fours console. See [Integrate HubSpot with Fours](/integrations/hubspot/). :::tip **Phase 4 complete when:** your CRM is connected to Fours and the integration is ready to use. ::: ## Phase 5: Co-Sell setup (optional) If you plan to co-sell with Microsoft and your Fours subscription includes Azure Co-Sell capabilities, complete this phase — otherwise, skip it. Azure Co-Sell lets you share sales opportunities with your Microsoft account team so they can collaborate with you throughout the sales cycle. **Estimated time:** ~15 minutes to configure field mapping, plus any additional time to complete Microsoft's co-sell requirements. Azure Co-Sell doesn't need a separate connection step — it rides on the Azure Marketplace integration from Phase 1, along with the **Referrals admin** role on your Microsoft side. See [Integrate Azure Co-Sell with Fours](/integrations/azure-cosell/) for the requirements. Once that's in place, configure field mapping yourself on the **Co-Sell** page's **Settings** tab, under **Configs**, so opportunities sync correctly between your CRM and Microsoft's co-sell platform — see [Co-Sell Configuration](/cosell/cosell-configuration/). Reach out to your Fours contact only if you need help with complex custom mappings. :::tip **Phase 5 complete when:** your Azure Co-Sell integration is connected and opportunity syncing has been configured. ::: ## You're live — what's next Congratulations! You're ready to start transacting with customers through Azure Marketplace using Fours. From here, your focus shifts from setup to day-to-day marketplace operations — creating private offers, managing agreements, tracking revenue, and growing your marketplace business. ### Self-serve customers Your onboarding is complete; post in your dedicated Slack channel or email [support@suger.io](mailto:support@suger.io), and expect a response within 1 business day. ### SMB / Mid-Market / Enterprise customers Your Customer Success Manager will schedule a post-launch check-in to help you plan your growth strategy, manage private offers, set up co-sell workflows, and answer product questions. ## Important links :::important Bookmark these — you'll want quick access to them once you're live. ::: | Resource | Where | | --- | --- | | Your Azure listings and offers | [Microsoft Partner Center — Marketplace Offers](https://partner.microsoft.com/en-us/dashboard/marketplace-offers/overview) | | Create a private offer | [Create an Azure Marketplace Private Offer](/azure-marketplace/create-private-offer/) | | Edit your product listing | [Update Your Azure Marketplace Listings](/azure-marketplace/update-product/) | | Check if an invoice has been paid | [Revenue Records](/revenue/revenue-records/) | | Learn more about the Fours console | [Navigate the Fours Console](/get-started/navigate-console/) | --- Source: https://doc.fours.com/azure-marketplace/integration/ # Integration Grant Fours the necessary access to manage your Azure Marketplace on our behalf, no more no less. --- ## Overview Selling on Azure Marketplace is managed through [`Microsoft Partner Center`](https://partner.microsoft.com/). Your business is required to enroll in the Microsoft AI Cloud Partner Program (formerly the Microsoft Partner Network) and obtain a verified Partner ID. Microsoft's guide to [enrolling in the partner program](https://learn.microsoft.com/en-us/partner-center/enroll/partner-center-enroll-overview) walks through the steps. ## Verify Account Eligibility Before you prepare any resources, confirm that your Microsoft Partner Center and Azure Portal are eligible to create a Marketplace listing. Work through the checklist below. 1. **Access Microsoft Partner Center** — Make sure you have valid login credentials, then sign in to the [Microsoft Partner Center](https://partner.microsoft.com/). 2. **Confirm Partner Center is linked to Azure** — Verify that your Partner Center account is connected to your Azure Portal. You can check this in the Azure Portal under the **Partner Center** section. 3. **Confirm program enrollment** — In Partner Center, open **Account Settings → Programs** and verify enrollment in both **Commercial Marketplace** and the **Microsoft AI Cloud Partner Program**. ![Partner Center program enrollment status](images/azure-account-eligibility-for-marketplac-1.png) 4. **Confirm legal compliance** — Make sure your organization is an approved partner and developer, and that all legal documentation is current and approved. ![Partner Center legal and agreements status](images/azure-account-eligibility-for-marketplac-2.png) 5. **Confirm your tenant is connected** — In Partner Center, open **Tenants** and confirm there is a tenant ID that matches your Azure Portal Tenant ID. ![Partner Center tenant management](images/azure-account-eligibility-for-marketplac-3.png) 6. **Complete payout and tax profiles** — Make sure your payout and tax profiles are fully completed and up to date, under **Payout and Tax** in Partner Center. ![Partner Center payout and tax profile](images/azure-account-eligibility-for-marketplac-4.png) 7. **Confirm roles and permissions** — The person running the integration must be a **Global Administrator** in both the Azure tenant and Microsoft Partner Center. The specific Partner Center roles Fours needs are granted to the Entra application (not the person) — see the Permissions Reference below. ![Partner Center user roles and permissions](images/azure-account-eligibility-for-marketplac-5.png) ## Prerequisite ### Permissions Reference Fours needs only the minimum access below. These permissions apply to **four distinct principals** — do not conflate the human operator with the Entra application. | Principal | Permission | Minimum | Notes | |---|---|---|---| | Human operator (runs setup) | Azure **Global Administrator** | Required | Only a Global Admin can grant admin consent for the Entra app. | | Human operator | Partner Center **Global Administrator** | Required | Needed to add the Entra application to Partner Center User Management. The operator does **not** personally need the individual Partner Center roles — those are assigned to the application. | | Entra application (Marketplace) | Service principal for the Marketplace SaaS Fulfillment API | Required | Entitlement/fulfillment sync; no declarative grant needed. | | Entra application (Partner APIs) | `user_impersonation` on the 3 Partner APIs + admin consent (+ Microsoft Graph `User.Read`) | Required | Partner Center API access / co-sell. | | Partner Center application roles (assigned to the Entra app) | **Developer**, **Business Contributor**, **Finance Contributor** | Minimum | Offer/product management, analytics, and payout sync. **Manager** and **Marketer** are optional convenience roles. | | Co-sell (Referrals) | **Referrals admin** role in the **Referrals workspace** user management | Optional | Only if you use co-sell / Referrals sync; assigned separately. | | Entra application (Microsoft Graph) | `Application.Read.All` | Optional | Lets Fours read the client secret's expiry date from the application object and warn you 30 days ahead — see [Client secret expiry warning](#client-secret-expiry-warning). Without it the integration works exactly as before, but you get no advance notice. | > The Quick Setup script configures every required Entra-application row automatically. `Application.Read.All` is not among them — add it by hand if you want the expiry warning. The Partner Center application roles and Referrals admin are assigned manually in Partner Center. Once your Microsoft AI Cloud Partner Program enrollment is verified, follow the steps below to prepare the resources required for the Fours integration. :::caution Required Access The person running this setup must have **Global Administrator** in both the Azure tenant **and** Microsoft Partner Center. Other Azure roles (e.g. Application Administrator) can create the app but typically cannot grant admin consent, which will block the integration. ::: ### Connect Microsoft Entra tenant Associate one `Microsoft Entra tenant` (formerly `Azure AD Tenant`) with your `Microsoft Partner Center` [tenants](https://partner.microsoft.com/en-us/dashboard/account/v3/tenantmanagement). ### Register Microsoft Entra application Choose **one** of the two paths below. Both end up with the same Microsoft Entra application (formerly Azure AD Application) configured with the right permissions and a client secret. | Path | Best for | Time | |---|---|---| | **A. Quick Setup (Script)** — *recommended* | A fresh setup with no existing Azure Marketplace integration | ~2 minutes | | **B. Manual Setup** | Customers who cannot run shell scripts, or who want to reuse an existing Microsoft Entra application | ~10 minutes | --- #### Path A — Quick Setup (Script) The script below creates the Microsoft Entra application, configures the redirect URI + implicit grant, adds the required API permissions, grants admin consent, generates a **1-year (365-day)** client secret, and self-verifies the end-to-end token flow — all in a single run. **Prerequisites for the script:** - **Azure CLI (`az`), `jq`, and `curl`** — the easiest way to satisfy all three is to use [Azure Cloud Shell](https://shell.azure.com) (everything is pre-installed). If you prefer to run locally, the script will print OS-specific install commands if a tool is missing. - **Signed in to the correct Azure tenant** — if not, the script will run `az login` for you (Cloud Shell is already signed in). - **You are a Global Administrator** in the target tenant (see the callout above). **Get the script:** Download setup-azure-app.sh — or view the source in the collapsible block below. **Run the script:** ```bash chmod +x setup-azure-app.sh ./setup-azure-app.sh ``` **Rotate the client secret** — before the 365-day expiry, or any time you want to invalidate the existing one: ```bash REUSE_EXISTING=true ./setup-azure-app.sh ``` The script appends a new secret without invalidating the old one, so there is **no downtime**. Paste the new value into the Fours Console with [Update Credential](#update-credential), then (optionally) remove the old secret from the Azure Portal after you've confirmed Fours is using the new one. When the script finishes, it prints three values to the terminal and also writes them to `./suger-azure-credentials.txt` (mode 600): - `TENANT_ID` - `APP_ID` (this is your `Client ID` / `Application ID`) - `CLIENT_SECRET` :::tip Secret rotation The generated secret is valid for **1 year (365 days)**. Before it expires, re-run the script with `REUSE_EXISTING=true` to append a new secret, then install it in the Fours Console with [Update Credential](#update-credential). The old secret stays valid until its natural expiry — you can remove it from the Azure Portal once you've confirmed Fours is using the new one. ::: :::danger Sensitive file The `suger-azure-credentials.txt` file contains your client secret in plain text. Copy the values to a password manager and **delete the file** immediately after. :::
Click to expand: full `setup-azure-app.sh` script ```bash #!/usr/bin/env bash # Suger Azure Marketplace — Azure-side one-shot setup script. # # In the customer's Azure tenant, this script configures the Entra app + permissions + secret in one run: # 1) Create (or reuse) a multitenant Entra application with Suger's Web redirect URI + implicit grant enabled # 2) Pre-create service principals for the Marketplace SaaS API + 3 Partner APIs # 3) Grant the app `user_impersonation` on the 3 Partner APIs (needed for co-sell) # (Marketplace SaaS API does not require a declarative grant — the token endpoint reads `resource=`) # 4) Grant admin consent # 5) Generate a client secret (default 365 days) # 6) Self-verify by exchanging the secret for a real Marketplace API token # At the end, the Tenant ID / App ID / Client Secret are printed and written to ./suger-azure-credentials.txt (chmod 600). # # Prerequisites (auto-detected — non-technical users do not need to install anything in advance): # - Azure CLI (az) + jq + curl: if missing, the script prints OS-specific install commands # (Azure Cloud Shell is the simplest option — all three are pre-installed) # - Azure login: if not signed in, the script will run `az login` (opens a browser) # - The executor must be a Global Administrator in the target tenant (required by Suger) # # Usage: # # First-time setup # ./setup-azure-app.sh # # # Rotate the client secret (run before the 365-day expiry; appends a new secret, # # the old one stays valid until its natural expiry — no downtime) # REUSE_EXISTING=true ./setup-azure-app.sh # # # —— Advanced options below; 99% of customers do not need these —— # SECRET_DAYS=90 ./setup-azure-app.sh # Customize secret lifetime (default 365 days) # APP_NAME="Suger Custom Name" ./setup-azure-app.sh # Customize the Entra app display name # SKIP_VERIFY=true ./setup-azure-app.sh # Skip token self-verification (offline/restricted networks) # CLEANUP=true ./setup-azure-app.sh # ⚠️ Dangerous: deletes same-named apps and recreates. Changes the App ID, breaking any existing offer Technical Configuration. Testing only # Note: -u has quirks with heredoc / command substitution on macOS bash 5.2, # so it's intentionally not enabled. We keep -e (exit on error) and pipefail. set -eo pipefail APP_NAME="${APP_NAME:-Suger Marketplace Integration}" SECRET_DAYS="${SECRET_DAYS:-365}" REUSE_EXISTING="${REUSE_EXISTING:-false}" CLEANUP="${CLEANUP:-false}" SKIP_VERIFY="${SKIP_VERIFY:-false}" OUTPUT_FILE="${OUTPUT_FILE:-./suger-azure-credentials.txt}" # Well-known Microsoft resource IDs in the public directory MARKETPLACE_SAAS_RESOURCE_ID="20e940b3-4c77-4b0b-9a53-9e16a1b010a7" # Marketplace SaaS Fulfillment API (client_credentials) MICROSOFT_PARTNER_RESOURCE_ID="4990cffe-04e8-4e8b-808a-1175604b879f" # MicrosoftPartner (legacy partner API) PARTNER_CENTER_RESOURCE_ID_1="fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd" # Microsoft Partner Center #1 PARTNER_CENTER_RESOURCE_ID_2="fabfbdc4-5751-471c-ac43-3826fa1afc31" # Microsoft Partner Center #2 SUGER_REDIRECT_URI="https://api.suger.cloud/public/integration/azure/authCode" # 3 Partner APIs that need user_impersonation PARTNER_RESOURCE_IDS=( "$MICROSOFT_PARTNER_RESOURCE_ID" "$PARTNER_CENTER_RESOURCE_ID_1" "$PARTNER_CENTER_RESOURCE_ID_2" ) # All resources that need an SP pre-created (includes Marketplace SaaS) ALL_RESOURCE_IDS=( "$MARKETPLACE_SAAS_RESOURCE_ID" "${PARTNER_RESOURCE_IDS[@]}" ) # OS detection (used for OS-specific install instructions) detect_os() { case "$(uname -s)" in Darwin*) echo "macos" ;; Linux*) if grep -qiE 'ubuntu|debian' /etc/os-release 2>/dev/null; then echo "debian" elif grep -qiE 'rhel|centos|fedora|rocky|alma' /etc/os-release 2>/dev/null; then echo "rhel" else echo "linux"; fi ;; MINGW*|CYGWIN*|MSYS*) echo "windows" ;; *) echo "unknown" ;; esac } # Friendly prompt when tools are missing: recommend Cloud Shell first, then local install missing_tools=() command -v az >/dev/null 2>&1 || missing_tools+=("az") command -v jq >/dev/null 2>&1 || missing_tools+=("jq") command -v curl >/dev/null 2>&1 || missing_tools+=("curl") if (( ${#missing_tools[@]} > 0 )); then echo "❌ Missing tools: ${missing_tools[*]}" echo echo "📦 Easiest option: use Azure Cloud Shell (browser-based, no install, auto-signed-in)" echo " → Open https://shell.azure.com, choose Bash, upload this script and run it" echo echo "To install locally:" case "$(detect_os)" in macos) echo " brew install azure-cli jq # curl is built into macOS" ;; debian) echo " curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash" echo " sudo apt-get install -y jq curl" ;; rhel) echo " sudo dnf install -y azure-cli jq curl" ;; windows) echo " Recommended: install WSL (Windows Subsystem for Linux) first, then follow the debian instructions" echo " Or install Azure CLI for Windows directly: https://aka.ms/installazurecliwindows" ;; *) echo " Azure CLI install docs: https://learn.microsoft.com/cli/azure/install-azure-cli" ;; esac exit 1 fi # Filter stderr noise (WARNING lines) but keep real errors visible. run_az() { local out rc tmperr tmperr=$(mktemp) if out=$(az "$@" 2>"$tmperr"); then grep -v "^WARNING" "$tmperr" >&2 || true rm -f "$tmperr" printf '%s' "$out" return 0 else rc=$? cat "$tmperr" >&2 rm -f "$tmperr" return $rc fi } # Wait for an SP to become visible in the directory (up to ~30s). wait_for_sp() { local id="$1" label="$2" i for i in $(seq 1 15); do if az ad sp show --id "$id" >/dev/null 2>&1; then return 0; fi sleep 2 done echo "❌ Timed out waiting for $label service principal (id=$id)" return 1 } echo "==> Current Azure context" if ! az account show >/dev/null 2>&1; then echo "⚠️ Not signed in to Azure — invoking az login..." echo " (Opens a browser. For headless/remote shells, run manually:" echo " az login --use-device-code --tenant )" if ! az login; then echo "❌ Login failed or cancelled" exit 1 fi fi az account show --query "{tenantId: tenantId, subscription: name, user: user.name}" -o table TENANT_ID=$(az account show --query tenantId -o tsv) read -r -p "Create/update the Suger integration app in this tenant? [y/N] " ans [[ "$ans" =~ ^[Yy]$ ]] || { echo "Cancelled"; exit 1; } echo echo "==> 1/6 Register Entra application (multitenant + Suger redirect URI + implicit grant): $APP_NAME" # CLEANUP=true: delete all same-named apps (including historical failures), then go through the fresh-create path if [[ "$CLEANUP" =~ ^([Tt]rue|1)$ ]]; then EXISTING_IDS="$(az ad app list --display-name "$APP_NAME" --query "[].appId" -o tsv 2>/dev/null || true)" if [[ -n "$EXISTING_IDS" ]]; then echo " CLEANUP=true → deleting same-named apps:" for id in $EXISTING_IDS; do run_az ad app delete --id "$id" echo " deleted $id" done else echo " CLEANUP=true → no same-named apps to delete" fi fi EXISTING_APP_ID="$(az ad app list --display-name "$APP_NAME" --query "[0].appId" -o tsv 2>/dev/null || true)" EXISTING_APP_ID="${EXISTING_APP_ID:-}" if [[ -n "$EXISTING_APP_ID" ]]; then if [[ "${REUSE_EXISTING:-false}" =~ ^([Tt]rue|1)$ ]]; then APP_ID="$EXISTING_APP_ID" echo " Exists → reusing APP_ID=$APP_ID" # Align existing app settings with the official requirements run_az ad app update --id "$APP_ID" \ --sign-in-audience AzureADMultipleOrgs \ --web-redirect-uris "$SUGER_REDIRECT_URI" \ --enable-id-token-issuance true \ --enable-access-token-issuance true >/dev/null echo " Aligned multitenant + redirect URI + implicit grant" else echo "❌ An app with the same name already exists (appId=${EXISTING_APP_ID})." echo " To re-run, set REUSE_EXISTING=true (keeps the app, re-applies permissions/consent + appends a new secret);" echo " or change APP_NAME to use a different name." exit 1 fi else APP_ID=$(run_az ad app create \ --display-name "$APP_NAME" \ --sign-in-audience AzureADMultipleOrgs \ --web-redirect-uris "$SUGER_REDIRECT_URI" \ --enable-id-token-issuance true \ --enable-access-token-issuance true \ --is-fallback-public-client false \ --query appId -o tsv) run_az ad sp create --id "$APP_ID" >/dev/null echo " Created APP_ID=$APP_ID" fi wait_for_sp "$APP_ID" "this app" echo echo "==> 2/6 Pre-create service principals for 4 Microsoft APIs" for RESOURCE_ID in "${ALL_RESOURCE_IDS[@]}"; do if az ad sp show --id "$RESOURCE_ID" >/dev/null 2>&1; then echo " $RESOURCE_ID already exists" else run_az ad sp create --id "$RESOURCE_ID" >/dev/null echo " $RESOURCE_ID created" fi wait_for_sp "$RESOURCE_ID" "$RESOURCE_ID" done echo echo "==> 3/6 Add API permissions" # Microsoft Graph User.Read: the portal adds this by default when creating an app via the UI, # but the CLI does not. Add it explicitly to match the portal-created standard. GRAPH_RESOURCE_ID="00000003-0000-0000-c000-000000000000" GRAPH_USER_READ_SCOPE_ID="e1fe6dd8-ba31-4d61-89e7-88639da4683d" run_az ad app permission add \ --id "$APP_ID" \ --api "$GRAPH_RESOURCE_ID" \ --api-permissions "${GRAPH_USER_READ_SCOPE_ID}=Scope" >/dev/null echo " Microsoft Graph User.Read ✓" # Marketplace SaaS: the SP is in the tenant; client_credentials flow does not require a declarative grant — skip echo " Marketplace SaaS: only requires SP in tenant; token endpoint reads resource=, no declarative grant needed" # 3 Partner APIs: add user_impersonation (delegated, required for co-sell flows) for RESOURCE_ID in "${PARTNER_RESOURCE_IDS[@]}"; do SCOPE_ID=$(az ad sp show --id "$RESOURCE_ID" \ --query "oauth2PermissionScopes[?value=='user_impersonation'].id | [0]" -o tsv 2>/dev/null || true) if [[ -n "$SCOPE_ID" ]]; then run_az ad app permission add \ --id "$APP_ID" \ --api "$RESOURCE_ID" \ --api-permissions "${SCOPE_ID}=Scope" >/dev/null echo " $RESOURCE_ID user_impersonation ✓" else echo " ⚠️ $RESOURCE_ID does not expose the user_impersonation scope, skipping" fi done echo echo " ⚠️ For co-sell, you also need to assign the Referrals admin role in the Partner Center Referrals workspace — see the docs" echo echo "==> 4/6 Grant admin consent + explicit grant (fallback)" # First run admin-consent (covers the whole app in one call) consent_ok=false for i in $(seq 1 10); do if run_az ad app permission admin-consent --id "$APP_ID" >/dev/null 2>&1; then consent_ok=true break fi sleep 3 done if ! $consent_ok; then echo "❌ admin-consent failed. Common causes:" echo " - The current account is not a Global Administrator (Suger requires Global Admin)" echo " - The tenant has disabled user/app consent" exit 1 fi # Known az CLI quirk: admin-consent returning 0 doesn't always mean OAuth2PermissionGrant was created. # Apply explicit `permission grant` as a fallback (idempotent — will not duplicate). sleep 3 # let admin-consent propagate for RESOURCE_ID in "$GRAPH_RESOURCE_ID" "${PARTNER_RESOURCE_IDS[@]}"; do SCOPE_VALUE="user_impersonation" [[ "$RESOURCE_ID" == "$GRAPH_RESOURCE_ID" ]] && SCOPE_VALUE="User.Read" run_az ad app permission grant \ --id "$APP_ID" \ --api "$RESOURCE_ID" \ --scope "$SCOPE_VALUE" >/dev/null 2>&1 || true done echo " ✓ admin-consent + explicit grant complete" echo echo "==> 5/6 Generate client secret (${SECRET_DAYS}-day validity)" # Use --end-date instead of --years for precise day-level expiry. Default 365 days # (~1 year) matches a standard secret-rotation cadence; rotate by re-running # with REUSE_EXISTING=true before expiry. SECRET_END_DATE=$( date -u -d "+${SECRET_DAYS} days" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null \ || date -u -v+"${SECRET_DAYS}"d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null ) [[ -n "$SECRET_END_DATE" ]] || { echo "❌ Could not compute secret expiry"; exit 1; } SECRET=$(run_az ad app credential reset \ --id "$APP_ID" \ --end-date "$SECRET_END_DATE" \ --append \ --display-name "suger-$(date +%Y%m%d)" \ --query password -o tsv) [[ -n "$SECRET" ]] || { echo "❌ Failed to generate client secret"; exit 1; } SECRET_EXPIRY_DATE="${SECRET_END_DATE%%T*}" echo echo "==> 6/6 Self-verify: exchange the new secret for a Marketplace API token" if [[ "$SKIP_VERIFY" =~ ^([Tt]rue|1)$ ]]; then echo " SKIP_VERIFY=true, skipping" else # Freshly-issued secrets occasionally take a moment to propagate in AAD — retry up to ~30s. verify_ok=false for i in $(seq 1 10); do resp=$(curl -sS -X POST \ "https://login.microsoftonline.com/${TENANT_ID}/oauth2/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=client_credentials" \ --data-urlencode "client_id=${APP_ID}" \ --data-urlencode "client_secret=${SECRET}" \ --data-urlencode "resource=${MARKETPLACE_SAAS_RESOURCE_ID}" || true) if echo "$resp" | jq -e '.access_token' >/dev/null 2>&1; then verify_ok=true break fi sleep 3 done if $verify_ok; then echo " ✓ Got a Marketplace API token — the end-to-end auth flow is working" else echo " ⚠️ Self-verification failed. Suger will likely also fail to authenticate. Last response:" echo "$resp" | jq . 2>/dev/null || echo "$resp" echo " Continuing to print credentials; resolve the issue before handing them over to Suger." fi fi # Persist credentials to a file to avoid scrollback/copy loss. umask 077 cat > "$OUTPUT_FILE" < Connection webhook: Save → republish the offer → the next Marketplace order will deliver a webhook to Suger. ⚠️ The App ID in Technical Configuration MUST equal the APP_ID above, or both directions break: - Suger rejects incoming MS webhooks on JWT aud mismatch - MS SaaS Fulfillment API rejects Suger's calls: "token is valid, however it does not include the correct audience, the entra tenant id, or the entra app id" ================================================================ ⚠️ The client secret was written to $OUTPUT_FILE. Copy it to a password manager, then delete that file. ================================================================ EOF ```
Once the script completes, skip ahead to [Add Azure AD Application to Partner Center](#add-azure-ad-application). --- #### Path B — Manual Setup Use this path if you cannot run shell scripts, or if you want to reuse an existing Microsoft Entra application (for example, when migrating from a self-built fulfillment system). Register a `Microsoft Entra application` in the previous `Microsoft Entra tenant`, ensuring that: 1. Add Web Redirect URL in the `Application`. The Redirect URL should be `https://api.suger.cloud/public/integration/azure/authCode`. > Web Redirect URL field in Entra application settings 2. Under `Implicit grant and hybrid flows`, check both: - **Access tokens (used for implicit flows)** - **ID tokens (used for implicit and hybrid flows)** > Implicit grant and hybrid flows checkboxes 3. Add the required API permissions. Go to **API permissions** → **+ Add a permission** → **APIs my organization uses**, and search for `Microsoft Partner`. The following APIs should appear: - `MicrosoftPartner` (App ID: `4990cffe-04e8-4e8b-808a-1175604b879f`) - `Microsoft Partner Center` (App ID: `fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd`) - `Microsoft Partner Center` (App ID: `fabfbdc4-5751-471c-ac43-3826fa1afc31`) For each of the three APIs, click on the API name, select the `user_impersonation` permission, and click **Add permissions**. > ![azure_portal_permission](images/azure_portal_permission.jpg) 4. Click **Grant admin consent for {your organization name}** to finalize the permissions. If the button is greyed out, your account is not a Global Administrator. 5. Generate a client secret under **Certificates & secrets → + New client secret**. Set the expiry to **1 year (365 days)** (recommended — matches a standard rotation cadence) and copy the **Value** immediately; you cannot view it again after leaving the page. :::warning The `MicrosoftPartner` API may not always appear by name. If you don't see it in the search results, try searching directly using the App ID: `4990cffe-04e8-4e8b-808a-1175604b879f`. If the application is still not appearing, open **PowerShell** from the [Azure Portal](https://portal.azure.com/) and run the following commands, then try again: ```powershell $Tenantid = '' $Appid = '4990cffe-04e8-4e8b-808a-1175604b879f' Connect-AzureAD -TenantId $Tenantid New-AzADServicePrincipal -ApplicationId $Appid ``` After running the commands, you can verify the service principal was created successfully: ```powershell Get-AzADServicePrincipal -ApplicationId $Appid ``` ::: ### Add Azure AD Application This step is required regardless of which path (A or B) you used above. Add the `Azure AD Application` created in the previous step to your `Microsoft Partner Center` [User Management](https://partner.microsoft.com/en-us/dashboard/account/v3/usermanagement#users). You can assign all five available roles (Manager, Developer, Business Contributor, Finance Contributor, Marketer); the minimum Fours requires is Developer, Business Contributor, Finance Contributor — see the Permissions Reference. > Assigning roles to the Azure AD Application in Partner Center :::tip Why all five roles? Granting all five is the path of least friction — it avoids re-visiting this step if Fours introduces a feature that depends on `Manager` or `Marketer` later. If your security policy requires least-privilege, grant only the minimum (Developer, Business Contributor, Finance Contributor) — see the Permissions Reference. For co-sell (Referrals sync), the additional **Referrals admin** role must be assigned separately in the **Referrals workspace** user management — it is not listed on this page. ::: ### Enroll Partner Programs There are two programs `Commercial Marketplace` and `Microsoft AI Cloud Partner Program` to enroll before we can start the marketplace listing and offers, as shown below in [`Microsoft Partner Center`](https://partner.microsoft.com/). > ![Commercial Marketplace and Microsoft AI Cloud Partner Program enrollment](images/partner_programs.png) ## Create Integration Now all required resources are ready from upper steps, then click the button `CONNECT` and fill the dialog of Azure integration on [Fours Console](https://console.suger.io/settings?tab=integrations) with info below. > ![azure_integration_form.jpg](images/azure_integration_form.jpg) - **Tenant ID**: The ID of the `Microsoft Entra tenant` associated with your `Microsoft Partner Center`. - **Client ID**: It is also called `Application ID`, It is the ID of the `Microsoft Entra application` created & added to your `Microsoft Partner Center`. - **Client Secret**: Also called `Application Secret`, `Secret Key`, or `Application Key`. If you used **Path A**, the script already printed it and saved it to `suger-azure-credentials.txt`. If you used **Path B**, you generated it manually in the Azure Portal — see the [Microsoft reference](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret). - **User ID** (optional): The email address to log in to `Microsoft Azure` and `Microsoft Partner Center`. - **User Secret** (optional): The password to log in to `Microsoft Azure` and `Microsoft Partner Center`. You can find the **Tenant ID** and **Client ID (Application ID)** on the Microsoft Entra application overview page: > ![app-id.png](images/app-id.png) :::caution Important If you already have a SaaS product listed in Microsoft Partner Center, the **Tenant ID** and **Client ID (Application ID)** you provide here **must match** the values configured in that product's **Technical Configuration**. > ![listing-app-id.png](images/listing-app-id.png) ::: :::tip - User ID and User Secret are optional. Provide them only if you want to enable [App + User authentication](https://learn.microsoft.com/en-us/partner-center/developer/partner-center-authentication#app--user-authentication) through Fours for connecting to Azure Marketplace APIs. When supplied, the User ID is the email address you use to log in to Microsoft Partner Center and the User Secret is the corresponding password, which Fours uses to securely verify your identity and complete the process. ::: Once clicked the button `CREATE`, you are redirected to Azure auth portal to grant OAuth code for the `Application` & Fours service. ### Integration settings Editing an existing Azure integration exposes two switches that change how Fours treats subscriptions and accepted offers. Both are **off by default**, and both describe what *your* systems do — turn one on only when the statement it makes is actually true of your organization. #### Self-Managed Subscription Activation *When enabled, your team activates Azure SaaS subscriptions yourself.* | | Off (default) | On | | --- | --- | --- | | Private offer form | Every private offer requests Azure auto-activation where the pricing schema defines it. | The offer form lets you choose **per offer** whether Azure auto-activates on purchase — **off by default**. | | Subscription sync | Activates any subscription still pending fulfillment, as a safety net. | Never activates a subscription. | Turning this on is what makes the per-offer **Auto-Activation** toggle appear on the private offer form — see [Create a Private Offer](/azure-marketplace/create-private-offer/). #### Treat Accepted Offers as Purchased *When enabled, your organization does not rely on Fours to sync Azure entitlements.* | | Off (default) | On | | --- | --- | --- | | Sub status | An accepted private offer with no entitlement carries **Pending Purchase**. | The sub status stays empty, whether or not an entitlement exists. | | Offer page | Shows the "accepted but not purchased" warning. | No warning. | | Reports | The unpurchased Azure offers report lists it. The report is emailed through the **Accepted but unpurchased offers digest** row of your [email notification](/settings/email-notification/) settings: **Enable Email Notification** must be on and that row enabled, and the offer's contacts receive it through the row's **Offer Notification Contacts** rule. | The report is not sent. | ### Connect more than one Azure account An organization can hold **several Azure Marketplace integrations** — useful when you publish from more than one Microsoft Entra tenant, for example after an acquisition or when a subsidiary sells under its own publisher profile. Connect each one the same way, with that tenant's own credentials. Each integration is identified by its **Tenant ID**, which stays stable when you rotate the App Registration behind it. Three rules apply: | Rule | What happens if you break it | | ---- | ---------------------------- | | One integration per Microsoft Entra tenant, per organization | The create is rejected: `an Azure Marketplace integration for tenant already exists in this organization`. Two App Registrations in the same tenant would sync the same publisher catalog twice. | | No duplicate tenant across integrations in the same organization | Same rejection — connect the second tenant instead, or edit the existing integration's credentials. | | At most one **co-sell-enabled** integration per organization | Connecting a second co-sell-enabled integration is rejected. Turn co-sell off on the other integration first if you need to move it. | The console can't change a connected integration's tenant ID or client ID: [Update Credential](#update-credential) replaces only the client secret. To move an existing integration to a different App Registration, contact [Fours Support](mailto:support@suger.io) rather than connecting a second integration. ## Complete Integration — Product Technical Configuration :::danger Important Creating the Azure integration in Fours alone is **not sufficient**. You **must** list at least one product (Public Offer) in Microsoft Partner Center, and ensure its **Technical Configuration** exactly matches the Fours integration settings. If they are inconsistent, Fours will **not** be able to retrieve entitlements, even though the integration itself appears to be successfully created. ::: When listing your product in Microsoft Partner Center, verify the following in the **Technical Configuration** section: - The **Microsoft Entra Tenant ID** is the same one used in the Fours integration. - The **Microsoft Entra Application (Client) ID** is the same one used in the Fours integration. - The **Landing Page URL** is set to the Fours-provided endpoint. - The **Connection Webhook** is set to the Fours-provided endpoint. :::tip For the exact values of Landing Page URL, Connection Webhook, and other Technical Configuration fields, refer to the [List Product — Technical Configuration](/azure-marketplace/list-product/#create-your-azure-marketplace-product-in-fours) page. ::: ## Migrate an Existing Listing to Fours Use this flow if you **already** have a live Azure Marketplace listing from a prior technical integration — one that already has a **Microsoft Entra Application ID** associated with it. Instead of registering a brand-new application, you reuse the existing one and reconfigure it for Fours. :::info Required access You need **Global Administrator** access in both the Azure Portal and Microsoft Partner Center. Partner Center roles are assigned to the Entra application, not to your account — see the Permissions Reference. ::: ### Step 1 — Retrieve your existing Entra Application ID 1. Sign in to [Microsoft Partner Center](https://partner.microsoft.com/). 2. Go to **Marketplace Offers** and select your **Live** listing. 3. Click **Technical Configuration**. 4. Copy the **Microsoft Entra Identity Application ID** shown on the page. ![Technical Configuration showing the Microsoft Entra Application ID](images/azure-marketplace-co-sell-migration-to-s-1.png) ### Step 2 — Locate the application in Azure 1. In a new tab, open the [Azure Portal](https://portal.azure.com/). 2. Search for **App registrations** in the top search bar. 3. Select **All Applications** and paste the Entra Application ID you copied in Step 1. 4. Select the matching application. ![Azure App registrations, All Applications view](images/azure-marketplace-co-sell-migration-to-s-2.png) ### Step 3 — Configure authentication settings 1. In the application overview, click **Authentication** in the left menu. 2. Add a platform and choose **Web**. ![Add a Web platform under Authentication](images/azure-marketplace-co-sell-migration-to-s-3.png) 3. Add the following redirect URI: ```plain https://api.suger.cloud/public/integration/azure/authCode ``` 4. Under **Implicit grant and hybrid flows**, check both: - Access tokens (used for implicit flows) - ID tokens (used for implicit and hybrid flows) ![Implicit grant and hybrid flows checkboxes](images/azure-marketplace-co-sell-migration-to-s-4.png) 5. Click **Configure** to add the Web platform, then save your changes. ### Step 4 — Add the required API permissions 1. In the left navigation under **Manage**, click **API permissions**. 2. Click **+ Add a permission**. 3. Select **APIs my organization uses**. 4. Search for **Microsoft Partner**. The following APIs should appear: - **MicrosoftPartner** (App ID: `4990cffe-04e8-4e8b-808a-1175604b879f`) - **Microsoft Partner Center** (App ID: `fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd`) - **Microsoft Partner Center** (App ID: `fabfbdc4-5751-471c-ac43-3826fa1afc31`) ![APIs my organization uses, Microsoft Partner search results](images/azure-marketplace-co-sell-migration-to-s-5.png) 5. For each of the three APIs: click the API name, select the **`user_impersonation`** permission, and click **Add permissions**. ![Selecting the user_impersonation permission](images/azure-marketplace-co-sell-migration-to-s-6.png) 6. Once all three APIs are added, click **Grant admin consent for _{your organization name}_**. If the button is greyed out, your account is not an Azure Global Administrator. ![Grant admin consent button](images/azure-marketplace-co-sell-migration-to-s-7.png) :::warning The **MicrosoftPartner** API may not always appear by name. If you don't see it, search directly using the App ID `4990cffe-04e8-4e8b-808a-1175604b879f`. If the application still doesn't appear, open **PowerShell** from the Azure Portal, run the following commands, then try again: ```powershell $Tenantid = '' $Appid = '4990cffe-04e8-4e8b-808a-1175604b879f' Connect-AzureAD -TenantId $Tenantid New-AzADServicePrincipal -ApplicationId $Appid ``` ::: ### Step 5 — Register the application in Partner Center 1. Return to [Partner Center](https://partner.microsoft.com/). 2. Go to **Account Settings → User Management → Microsoft Entra Applications**. 3. Your application is likely already on the list. Select it and **delete** it — you will add it again. 4. Click **+ Add Microsoft Entra Application → Continue**. 5. Assign **all 5 available permissions** to the application. 6. Click **Add**. ![Adding the Entra Application with all five permissions in Partner Center](images/azure-marketplace-co-sell-migration-to-s-8.png) ### Step 6 — Generate the Client ID and Client Secret 1. In the Entra Applications list, click the name of the application you added. 2. In the detail panel, click **Add new key** to generate your credentials. ![Generate a new key for the Entra Application](images/azure-marketplace-co-sell-migration-to-s-9.png) 3. You will receive a **Client ID** and a **Client Secret** (Key). :::warning Important Copy and securely save both the Client ID and the Key immediately. You'll need to enter these into the Fours Console when setting up the Azure Marketplace integration. ::: ### Step 7 — Connect your Azure Marketplace account to Fours 1. Go to the [Fours Console](https://console.suger.io/settings?tab=integrations) and open the **Integrations** section. 2. Find the **Azure Marketplace** integration card and click **Connect Now**. 3. Provide the following: - **Tenant ID** — found in Partner Center under **Account Settings → Tenants**. - **Client ID** and **Client Secret** — generated in Step 6. - **Partner Auth Resource Type** — if you added the **MicrosoftPartner** API (`4990cffe-04e8-4e8b-808a-1175604b879f`), select **Microsoft Partner**. If that API was not available, select **Microsoft Partner Center**. ![Fours Console Azure Marketplace connection dialog](images/azure-marketplace-co-sell-migration-to-s-10.png) 4. Click **Create**. You'll be redirected to your Partner Center account to confirm the integration. Click **verify**; you should receive confirmation that the integration was established. ### Step 8 — Update your product listing's Technical Configuration 1. Go to [Marketplace Offers](https://partner.microsoft.com/en-us/dashboard/marketplace-offers/overview) and select a product. 2. Click **Technical Configuration** and enter the following: - **Landing Page URL:** `https://api.suger.cloud/public/signup/azure/orgId/{your-suger-org-id}` - **Connection Webhook:** `https://api.suger.cloud/public/azure/fulfillment/webhook/orgId/{your-suger-org-id}` - **Microsoft Entra Tenant ID:** the ID of the Microsoft Entra tenant associated with your Microsoft Partner Center (see [Prerequisite](#prerequisite)). - **Microsoft Entra Identity Application ID:** the ID of the Microsoft Entra application added to your Microsoft Partner Center (see [Prerequisite](#prerequisite)). 3. Click **Review & Publish**. This lets Fours pull historical Azure revenue and co-sell data. ![Product Technical Configuration with Fours landing page and webhook URLs](images/azure-marketplace-co-sell-migration-to-s-11.png) :::tip Your Fours org ID is shown at the top center of the [Users & Roles settings page](https://console.suger.io/settings?tab=users_roles). ::: ## Verify the Integration You can re-verify the integration at any time — click **Verify** on the Azure integration card in [Settings → Integrations](https://console.suger.io/settings?tab=integrations). Verification checks that your credential can obtain a Microsoft Entra token and access the Partner Center APIs. - **Verified with warnings** (orange icon) — the integration works, but the icon's tooltip lists non-fatal issues. The most common one is a client secret nearing its expiry — see [Client secret expiry warning](#client-secret-expiry-warning). - **Verification failed** — the integration is not fully working. The integration card shows fix hints. Two cases account for most failures: - **Azure rejected the credential** — for example an expired client secret (rotate it, then install the new one with [Update Credential](#update-credential)), or an application that has not been granted its Partner Center roles. - **The Microsoft sign-in step was never completed** — no Partner Center user authorization is stored, so co-sell referral sync and Commercial Marketplace Analytics payout reports cannot run. Re-connect the Azure integration and finish the Microsoft sign-in window. The application needs `user_impersonation` consent, which a Global Administrator may have to grant first; alternatively supply the Partner Center user name and password. A failed re-verify never disables an already-working integration. An integration that already reached **Verified** keeps that status and keeps syncing products, offers, entitlements, and revenue on its service principal — the failure tells you which capabilities are degraded, not that everything stopped. Fours also re-verifies connected Azure integrations automatically once a day. If the credential is rejected, Fours alerts you by email — add recipients for the `CONNECTION_FAILED.INTEGRATION` scope in the [email notification configuration](/settings/email-notification/#configuration) — and fires the **Connection Failed - Integration** event in the [Fours Notification Event Trigger](/workflow/suger-notification-event-trigger/). ### Client secret expiry warning An expired client secret stops every Azure sync at once: Microsoft refuses each token request with `AADSTS7000222`, and nothing recovers until the secret is rotated. Because a secret can be valid for up to two years, that deadline is easy to lose track of. So the verify flow — including the daily automatic one — reads the secret's expiry from your application in Microsoft Entra and warns once it is within **30 days**. The integration card shows a warning while the credential still works, naming the exact expiry date and pointing at the rotation steps: **Azure Portal → App registrations → your app → Certificates & secrets**, create a new client secret, then paste it into the Fours integration with [Update Credential](#update-credential). Reading that date needs the `Application.Read.All` Microsoft Graph permission on the application. If it was never granted, or the stored secret cannot be matched against the application's secrets, Fours simply does not warn — track the expiry yourself and rotate ahead of it. :::note Replaces the old refresh-token warning Earlier versions of this check warned 14 days ahead about the Partner Center refresh token instead. That warning is gone, and the API field that carried it is now `clientSecretExpiresOn`. If you read integration data through the Fours API and looked for `refreshTokenExpiresOn`, read the new field. ::: ## Update Credential When your client secret nears its expiry — or you rotate it for any other reason — install the new secret with **Update Credential** rather than editing or reconnecting the integration: 1. Create the new client secret in the Azure portal (or re-run the setup script with `REUSE_EXISTING=true`). 2. In [Settings → Integrations](https://console.suger.io/settings?tab=integrations), open the Azure Marketplace card's **⋯** menu and choose **Update Credential**. Only an Admin sees this option. 3. Paste the new value into **Client secret** and click **Update**. Only the secret changes. The tenant, the client ID, the Partner Center sign-in and every setting on the integration stay as they are, and Fours verifies the integration again as soon as the secret is saved. ## Edit Integration You can edit the integration to update the following fields. The client secret is not one of them: it expires on a schedule (365 days / 1 year by default if generated via Path A), every sync stops silently when it lapses, and you replace it with [Update Credential](#update-credential). - **Enable Entitlement End Soon Notification**: When enabled, specify the number of days (10-60) before an entitlement ends to trigger notifications. Fours will send an initial notification when Azure Marketplace entitlements approach ending, followed by reminders every 5 days. To configure recipients, follow the [email notification configuration guide](https://doc.fours.com/settings/email-notification/#configuration) and add the scope `END_SOON.ENTITLEMENT`. :::tip Rotate the client secret If you used **Path A**, rotate the secret by re-running the script with `REUSE_EXISTING=true ./setup-azure-app.sh` — it appends a fresh secret to the same app and prints the new value. Then install it with [Update Credential](#update-credential). The old secret stays valid until its natural expiry, so there is no downtime. ::: ## Delete Integration The Azure integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the **Application Key** will be deleted immediately & permanently from Fours. No time window or methods to recover. --- Source: https://doc.fours.com/azure-marketplace/pricing-model/ # Pricing Model Azure Marketplace Pricing Models --- ## Overview There are two pricing models for the SaaS product in Azure marketplace: [Flat Rate](#flat-rate) and [Per User](#per-user). You can choose only one price model for each of your SaaS product offer. Only the **Flat Rate** model support optional usage-based pricing. :::warning - After your offer/product is published, you cannot change the pricing model. In addition, all plans for the same offer must share the same pricing model. ::: ## Flat Rate Enable access to your service with a single monthly or annual flat rate price. This is sometimes referred to as site-based pricing. With this pricing model, you can optionally define metered plans that use the marketplace metering service API to charge customers for usage that isn't covered by the flat rate. You should also use this option if usage behavior for your SaaS service is in bursts. Below is an example of Flat Rate plan. - Two billing terms: 1-month and 1-year with different prices. - One usage metering dimension `consumption_unit` with price $0.1 per unit. - For 1-month billing term, 990 of `consumption_unit` are already included in base, which means that the first 990 unit of usage metering won't charge the buyer for extra payment. - For 1-year billing term, 10000 of `consumption_unit` are included in base. > Example Flat Rate plan with a usage metering dimension ## Per User Enable access to your service with a price based on the number of users who can access the offer or occupy seats. With this user-based model, you can set the minimum and maximum number of users supported by the plan. You can create multiple plans to configure different price points based on the number of users. Below is an example of Per User plan. - There billing terms: 1-month, 1-year and 2-year with different prices per user. - Set minimum number of users as 5. Not maximum users limit. - The 2-year billing term is set with `per year` payment option instead of the default `one-time`. > Example Per User plan with multiple billing terms --- Source: https://doc.fours.com/azure-marketplace/list-product/ # List Product List your SaaS products in Azure Marketplace, fully managed by Fours on your behalf. --- ## Overview You can list your SaaS products via [Microsoft Partner Center](https://partner.microsoft.com/en-US/), so your clients can search & buy your services in [Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/). In Fours, a **product** is your centralized listing configuration and system of record. In Azure Marketplace, buyers see and purchase an **offer**. Each product in Fours maps to one Azure Marketplace offer. :::info In Microsoft Partner Center, all products are listed as an **Offer**. The **Offer** in Azure is equivalent to the **Product** in AWS, GCP, and the Fours platform. ::: This guide walks you through filling out the listing form in Fours, submitting it, and finishing the publishing process in Partner Center. ## Prerequisites Make sure the following are already in place before creating your listing in Fours. ### Azure Marketplace - **Partner Center Account and Program Enrollment** — Create a Microsoft Partner Center account and enroll in both the Commercial Marketplace program and the Microsoft AI Cloud Partner Program. See [Create a Microsoft Marketplace account in Partner Center](https://learn.microsoft.com/en-us/partner-center/account-settings/create-account). The Commercial Marketplace program is added under **Settings > Account Settings > Identifiers > Publisher** tab. - **Profile Verification** — Fully complete and verify your Legal Info, Payout profile, and Tax profile within Partner Center. See [Set up Microsoft Marketplace payout and tax profiles](https://learn.microsoft.com/en-us/partner-center/account-settings/set-up-your-payout-account). - **Entra ID and App Registration** — Associate your Microsoft Entra ID tenant with your Partner Center account (in the [Tenant](https://partner.microsoft.com/en-us/dashboard/account/v3/tenantmanagement#commercial) tab) and register a new Microsoft Entra Application with the required API permissions. See [Register a SaaS application](https://learn.microsoft.com/en-us/partner-center/marketplace-offers/pc-saas-registration). For more details on the Microsoft Entra tenant ID and Application ID, see the [Azure integration prerequisites](/azure-marketplace/integration#prerequisite). ### Fours You need **Admin** access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). ## Create Your Azure Marketplace Product in Fours ### Step 1: Start a new product draft 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product), then click **+ New Product**. ![+ New Product button in the Fours Console](images/create-and-publish-an-azure-marketplace--1.png) 2. Select **Azure Marketplace** as the **Marketplace**. ![Selecting Azure Marketplace in the Fours Console](images/create-and-publish-an-azure-marketplace--2.webp) This opens the Azure listing configuration form. Complete the fields described below. :::tip Use the ✨ **AI Autofill** feature to help generate initial descriptions, categories, and keywords. Click **AI Auto Fill**, enter your website URL, and click **Submit**. The AI pulls data from your website to pre-fill your listing information. AI Autofill is a starting point only — it may make assumptions based on your website, so always review and adjust the results before saving. ![AI Auto Fill](images/create-a-product-listing-saas-3.png) ::: ### Step 2: Complete Basic Information Review and complete the following fields. **Basic Information & Marketing** - **Product ID** _(Required)_ — Your unique internal identifier. Use only lowercase letters, numbers, dashes, or underscores. Cannot end in `-preview`. Think of it as a short code for your product. For example, if your public product title is "Contoso SaaS Platform", your Product ID could be `contoso-saas`. Once you click **Create**, you can't change it. - **Product Alias** _(Required)_ — An internal reference name just for you inside Microsoft Partner Center. Buyers won't see this, and you can simply reuse your Product ID here. - **Product Title** _(Required)_ — The name that customers see in Azure Marketplace. Make it clear and descriptive so buyers immediately understand what the product is. - **Primary Category** _(Required)_ — The main category where your product should appear. This helps Microsoft organize the Marketplace and lets customers find you more easily. - **Secondary Category** _(Required)_ — An optional additional category to help further classify your product and support storefront placement and discoverability. - **Description** _(Required)_ — A few paragraphs that explain what your product does, who it's for, and what problem it solves. Include: 1) a product overview, 2) your target user, and 3) the customer problem your product solves. Write in plain language; don't assume the customer already knows your product. Up to 5,000 characters. - **Search Result Summary** _(Required)_ — A one-line summary that appears in search results. Keep it short and precise, plain text with no line breaks, so people understand the purpose at a glance. - **Getting Started Instructions** _(Required)_ — Step-by-step guidance for a customer to start using your product after purchase. Focus on the essentials: login, setup, or connection steps. If you don't have a well-defined PLG motion, explain how your company will start account provisioning with the customer after purchase. - **Search Keywords** _(Required)_ — Up to 3 words or phrases that match what customers might type when looking for your product. Use words that also appear in your Description and Summary to improve search relevance. **Media & Resources** - **Company Logo** _(Required)_ — Your brand identity in the marketplace. Upload a PNG square company logo between 216x216px and 350x350px (for example, 280x280px). - **Screenshot** _(Required)_ — Upload a 1280x720px PNG image that clearly shows your product interface or key features. Add a short caption to provide context. - **Supporting Document** _(Required)_ — Upload a PDF file containing sales or marketing assets (such as brochures or checklists) and a caption to back up your claims. - **Resources** _(Required)_ — Click **+ Add resource** to add helpful links like documentation, FAQs, forums, or release notes. You can add up to 10 resources. :::warning Microsoft strictly enforces formatting requirements for logos and screenshots. If your files do not match the exact specifications, your listing will be **rejected** during certification. - Your **logo** must be a perfect square within the allowed dimensions (216x216px to 350x350px). - Your **screenshot** must be exactly 1280x720px. You can use a free tool like [iLoveIMG](https://www.iloveimg.com/resize-image) to resize or crop your images before uploading them to Fours. ::: **Audience, Legal & Contacts** - **Preview Audience** _(Required)_ — The Microsoft email addresses of users who need permission to view the hidden preview of your listing before it goes live, along with an optional description for context (for example, _reviewer helping with the listing creation process_). You can add up to 10 audiences. - **Support Contact** _(Required)_ — Contact info (name, email, phone, and support URL) for Microsoft partners to use when your customers open support tickets. This info isn't listed in the marketplace. - **Engineering Contact** _(Required)_ — An internal contact (name, email, phone) for Microsoft to reach in case of technical issues. - **Cloud Solution Provider (CSP) Program Contact** _(Required)_ — The internal contact person (name, email, phone) for CSP or reseller partnerships related to your product. - **CSP Program Marketing Materials URL** _(Required)_ — A link where CSP partners can access your marketing materials. Only relevant if you support the CSP program. - **Privacy Policy URL** _(Required)_ — A link to your privacy policy hosted on your site. This is required, and the link must be valid and publicly accessible. ### Step 3: Add Pricing Information Start by choosing a **Pricing Model**. Each plan can use one of two [pricing models](/azure-marketplace/pricing-model): either [Flat Rate](/azure-marketplace/pricing-model#flat-rate) (per site) or [Per User](/azure-marketplace/pricing-model#per-user) (per seat). All plans in the same offer must share the same pricing model — an offer cannot have one plan that's flat rate and another that's per user. If you plan on mostly transacting via [Private Offer](/azure-marketplace/create-private-offer), we recommend Flat Rate. :::warning You can't change the pricing model after the offer is published. ::: **Flat Rate** — Use Flat Rate when you want to charge a fixed price per plan, regardless of the number of users. 1. (Optional) Add a **Usage Dimension**. This lets you charge for metered overages or consumption-based add-ons that fall outside the fixed contract price. - **Tip:** As a best practice, add at least one generic usage dimension with a price of $0.01 to allow future billing flexibility. 2. Add a **Plan**. Each plan represents what customers can purchase (e.g. Basic, Pro, Enterprise). 3. (Optional) **Add Billing Term** if you want to offer multiple contract durations under the same plan. 4. (Optional) Select **+ Add Plan** to create additional tiers. **Per User** — Use Per User pricing when your product charges based on the number of users in an account. 1. Add a **Plan**. Each plan represents what customers can purchase (e.g. Basic, Pro, Enterprise). 2. (Optional) Set user limits — the minimum and maximum number of users a plan supports. 3. (Optional) **Add Billing Term** if you want to offer multiple contract durations under the same plan. 4. (Optional) Select **+ Add Plan** to create additional tiers. Each plan requires the following fields: | Field | Description | |---|---| | **Plan ID** | Unique identifier for the plan. For a plan called _Contoso Platform Access_, a good ID is `contoso-platform-access`. | | **Name** | Plan name. | | **Description** | Overview of what's included. | | **Billing Term** | Per month, per year, per 2 years, or per 3 years. | | **Price (USD)** | The plan price in US dollars for each billing term. | You can define multiple plans, but make sure every field is completed on each one. #### Usage Dimensions (Optional but Recommended) We strongly recommend adding at least one generic usage dimension to enable more flexible, usage-based pricing. Azure does **not** allow changes to the pricing model after a plan is published — without a usage dimension in place, charging for overages or additional usage later would require creating a new plan from scratch. | Field | Description | |---|---| | **ID** | Unique identifier for the usage metric. | | **Display Name** | What the usage metric will be called. | | **Unit of Measure** | Unit that defines the metric (e.g., GB, user, transaction). | | **Price (USD)** | Cost per unit. | :::tip To simplify future billing, consider adding a generic usage dimension with a price of **$0.01** (e.g., `overage_dimension`). This makes it easy to charge customers for additional usage by multiplying the reported quantity. For example, to bill a customer **$1,527.16** in overages, report a quantity of **152,716** units. Multiplied by $0.01, this results in the exact amount you want to charge. ::: ### Step 4: Save, Preview, or Create - **Save as draft** — Use this while you're still filling things out, or if your Azure Marketplace integration is not yet complete. - **Preview** — Always check this before publishing to catch issues. - **Create** — This finalizes your listing. Once you hit **Create**, you're moving forward with publishing, so make sure everything is complete and accurate. ![Review and create the listing](images/create-a-product-listing-saas-4.png) Your listing is created in a **Pending** status in Fours. To continue the submission, the next steps happen within your connected Partner Center account. If you need help during setup or defining next steps, contact the Fours Support team at support@suger.io. ## Technical Setup in Microsoft Partner Center After your draft syncs from the Fours Console, add your Fours endpoints to the **Technical configuration** tab in Partner Center. :::info After creating your listing in Fours, it may take up to 10 minutes for the offer to appear in **draft mode** within Partner Center. ::: 1. **Navigate to Technical Configuration** — Open your draft listing in Partner Center and go to the Technical configuration tab. For step-by-step navigation, see [Add technical details for a SaaS offer](https://learn.microsoft.com/en-us/partner-center/marketplace-offers/create-new-saas-offer-technical). 2. **Enter your Fours endpoints and Microsoft Entra credentials** — Paste the following values when prompted. 3. **Save your work** — Click **Save draft** before leaving the page. > Technical configuration tab with Fours endpoint fields in Partner Center | Input Field | Value | | ----------- | ----- | | Landing page URL | `https://api.suger.cloud/public/signup/azure/orgId/{your-suger-org-id}` | | Connection webhook | `https://api.suger.cloud/public/azure/fulfillment/webhook/orgId/{your-suger-org-id}` | | Microsoft Entra tenant ID | The ID of the `Azure AD Tenant` associated with your `Microsoft Partner Center`. See the [Azure integration prerequisites](/azure-marketplace/integration#prerequisite) for details. | | Microsoft Entra application ID | The ID of the `Azure AD Application` created & added to your `Microsoft Partner Center`. See the [Azure integration prerequisites](/azure-marketplace/integration#prerequisite) for details. | :::warning These values must exactly match your Fours integration. Any mismatch will stop Fours from tracking purchases and issuing entitlements. ::: ## Publish and Go Live Once your listing status in Fours changes to **Pending**, complete the submission in Microsoft Partner Center. 1. **Complete Supplemental Content** — Navigate to [Microsoft Partner Center](https://partner.microsoft.com/), go to **Marketplace offers**, locate your newly created draft listing, and open the _Supplemental content_ tab. Fill in all required fields and click _Save draft_. 2. **Review and Publish** — Return to _Offer overview_, click _Review and publish_, check for any remaining issues that need attention, and click _Publish_ (or _Submit_) to submit your product for certification. 3. **Go Live** — Azure generates a preview version of your listing within approximately 45 minutes (allow up to 1–2 hours). Then return to _Offer overview_ in Partner Center and click _Go live_ to officially submit the offer for Microsoft's review. Skipping this step means your product won't appear publicly. Once live, Fours automatically updates the product status. ### How Fours reconciles the product status Each hourly sync asks Azure whether the offer is live in the store, then reconciles the Fours product status to match. You don't need to change the status by hand: | Azure says | Current Fours status | Becomes | |---|---|---| | Live in the store | `UNLISTED`, `DRAFT`, `PENDING`, or `PENDING_CREATE` | `PUBLIC` | | Not in the store | `PUBLIC` | `UNLISTED` | | Either | `EDITED`, `DELETED`, or `UPDATE_FAILED` | Unchanged | A product that isn't live yet is never archived by this — only a previously public product moves back to `UNLISTED`. In-progress states are left alone so a genuine draft is not mistaken for a withdrawn listing. :::info Why a live product used to sit in Draft Azure omits the lifecycle state on a resource that is already live. A product first synced in that condition used to default to `Draft` and stay there even after going live. The reconcile above fixes those products on the next sync, so an older listing stuck in `Draft` should correct itself within the hour. ::: ## Set Product Signup URL The last step is connecting your Azure listing to your actual software so buyers can register and start using it. Without this, purchases go through, but users won't know where to sign up. Fours automatically syncs with `Azure Partner Center` and pulls all your listed products' info. You can see all your listings on the [Fours Console Product page](https://console.suger.io/product). 1. **Open your product** — Log in to the Fours Console, go to the _Product_ tab, and select your Azure product. 2. **Edit product info** — On the overview page, find _Product Info_ and click **Edit**. 3. **Add your Fulfillment URL** — Paste the direct link to your software's signup or registration page (for example, `https://your-app.com/signup`) and click **Save**. Once saved, your automated provisioning flow is active. ## Signup URL Redirect 1. After purchasing the product, your buyer is directed to `https://api.suger.cloud/public/signup/azure/orgId/your-suger-org-id` first. 2. Then they are redirected to your product Signup URL with two query parameters `sugerEntitlementId` & `partner` — for example, `https://your-product-signup-url?sugerEntitlementId=1234abcd&partner=azure`. 3. Your service needs to collect this `sugerEntitlementId` and save it with the account created by the buyer. 4. See [how the sign-up URL redirect works](/settings/signup-url-redirect/#how-it-works). **How it works for buyers:** - **Purchase** — The buyer completes the transaction in Azure. - **Fours Intercept** — Fours securely validates the purchase and creates an entitlement in your console. - **Final Redirect** — Fours redirects the buyer to your Fulfillment URL with parameters that let your system grant immediate access. ## Make Your Listing Azure Benefit Eligible (MACC) Once your listing is live, you can work toward making it **Azure benefit eligible** — Microsoft's designation that a purchase counts toward the buyer's [Microsoft Azure Consumption Commitment (MACC)](https://learn.microsoft.com/en-us/marketplace/azure-consumption-commitment-benefit). When an offer is benefit eligible, 100% of the pretax purchase amount draws down the customer's Azure commitment, and buyers see an **Azure benefit eligible** label on your offer in the Azure portal. This makes your product far more attractive to enterprise customers who hold an active Azure commitment. For how commit drawdown works across clouds, see [Cloud Commits and Drawdown](/concepts/commit-drawdown). :::info There is **no separate MACC application form**. Microsoft automatically enrolls your offer in MACC — typically within one week — once the offer reaches **Azure IP Co-sell eligible** status. "Applying" for benefit eligibility therefore means meeting Microsoft's Azure IP Co-sell requirements. Enrollment is tracked **per offer**, so every offer you want to count toward MACC must qualify individually. ::: ### Step 1: Reach Co-sell Ready status Azure IP Co-sell eligibility builds on **Co-sell Ready** status. In [Partner Center](https://partner.microsoft.com/), make sure you have: - A complete [business profile](https://learn.microsoft.com/en-us/partner-center/customers/create-a-marketing-profile). - Your offer **published live** on Microsoft Marketplace — complete the [Publish and Go Live](#publish-and-go-live) steps above first. Free and BYOL offers aren't transactable and don't qualify. - A **sales contact** for each co-sell-eligible geography. - The required listing details and collateral (a one-pager and a pitch deck) on the **Co-sell > Solutions** page. See [Configure co-sell for a Microsoft Marketplace offer](https://learn.microsoft.com/en-us/partner-center/referrals/co-sell-configure). ### Step 2: Meet the Azure IP Co-sell requirements After reaching Co-sell Ready, your SaaS offer must also meet Microsoft's four [Azure IP Co-sell requirements](https://learn.microsoft.com/en-us/partner-center/referrals/co-sell-requirements): 1. **Revenue threshold** — At the organization level, generate at least **USD $100,000** in Azure Consumed Revenue or Marketplace Billed Sales over the trailing 12 months. Azure credits don't count toward this figure. 2. **Azure-platformed technical validation** — Your solution must be primarily hosted on Azure and pass Microsoft's technical validation. 3. **Reference architecture diagram** — Upload a reference architecture diagram with your co-sell documents in Partner Center (required for SaaS offers). See [Reference architecture diagram](https://learn.microsoft.com/en-us/partner-center/referrals/reference-architecture-diagram). 4. **Transactable offer** — Your offer must be transactable on Microsoft Marketplace, which Fours-managed listings already are. Your solution type must be **IP** and your offer type must be **SaaS**, **Azure Application**, **Azure Container**, or **Azure Virtual Machine**. Fours-managed listings are created directly as SaaS. For Azure Container offers, the offer is created in Partner Center first, then synced into Fours, after which Fours fully manages offers, entitlements, and revenue the same as a SaaS listing. ### Step 3: Confirm enrollment in Partner Center After your offer becomes Azure IP Co-sell eligible, verify MACC enrollment: 1. Sign in to [Partner Center](https://partner.microsoft.com/dashboard/home) and select the **Marketplace offers** tile. 2. Open your offer and go to the **Offer overview** page. 3. In the **Marketplace programs** section, confirm that **Microsoft Azure consumption commitment** shows **Enrolled**. :::warning Even when your offer is enrolled, two conditions determine whether a specific purchase actually draws down the buyer's MACC: - **Azure-only deployment** — The benefit applies only to licenses used exclusively in Azure. Hybrid or on-premises deployments are excluded. - **Azure portal path** — The customer must complete the purchase through the **Get it in Azure portal** button. Purchases made directly on Microsoft Marketplace by credit card do not contribute to MACC. ::: If you need help getting your Fours-managed listing to benefit-eligible status, contact the Fours Support team at support@suger.io. ## FAQ ### Do we need any extra development? We only want to sell via the Azure Marketplace, so it won't be part of the actual Azure solution. You can get your solution listed on Azure without any extra development. ### Can I transact with a private (not visible to the public) listing? Azure doesn't allow private listings to be transactable, so the product must be live. ### My listing submission keeps failing. What setup am I missing? The most common blocker is incomplete tax and payment profiles in Partner Center. These must be fully completed and verified before your listing can be published. See [Set up Microsoft Marketplace payout and tax profiles](https://learn.microsoft.com/en-us/partner-center/account-settings/set-up-your-payout-account) for instructions. ### How should I price my Azure listing? Do I need public pricing like AWS? Unlike AWS, Azure doesn't require public pricing. You can create listings that are only available through private offers. However, if you do set public pricing, consider using placeholder pricing to encourage private offer requests. Azure supports different pricing models including flat-rate annual commits and per-user pricing, but avoid complex multi-dimensional pricing that might hit Azure's limits. ### Does my Fours-managed Azure listing count toward a customer's Azure commitment (MACC)? Only if the offer is **Azure benefit eligible**. Microsoft enrolls your offer in MACC automatically — typically within a week — once it reaches Azure IP Co-sell eligible status, and the customer must complete the purchase through the Azure portal path. See [Make Your Listing Azure Benefit Eligible (MACC)](#make-your-listing-azure-benefit-eligible-macc) for the full process. --- Source: https://doc.fours.com/azure-marketplace/update-product/ # Update Product Update your published Azure Marketplace listings from the Fours Console and Microsoft Partner Center. --- ## Overview What you can change on an Azure listing depends on where the listing is in its lifecycle. Some changes — like the fulfillment URL — can be made directly in the [Fours Console](https://console.suger.io/product). Others, such as descriptions, plans, and pricing, must be made in [Microsoft Partner Center](https://partner.microsoft.com/en-US/), which Fours keeps in sync once your changes are published. ## Prerequisites - Access to [Microsoft Partner Center](https://partner.microsoft.com/). - Contributor or higher-level permissions on the Azure listing. - An active and published Azure product listing. - For fulfillment URL edits in Fours, **Admin** access to the Fours Console. If you don't have access yet, ask your organization admin to invite you. ## What You Can Edit by Listing Status | Status | Visibility | What you can edit in Fours | |---|---|---| | `Draft` | Private (Fours Console) | Full access — pricing, plans, draft, and preview before submitting to Azure | | `Preview` | Preview audience | Fulfillment URL only. All other changes must be made in Partner Center. | | `Live` | Public | Fulfillment URL, history, metadata, and private offers | ## Update the Fulfillment URL 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product). 2. Open the relevant Azure listing. 3. Click **More actions** in the top right corner, then **Edit Fulfillment URL**. ![Edit Fulfillment URL in the Fours Console](images/update-your-azure-marketplace-listings-1.webp) 4. Make your changes and click **Save** to sync them to Azure. ## Edit Core Listing Details in Partner Center Azure product listings (descriptions, plans, marketing content, pricing, and other core details) **cannot be edited through the Fours Console**. All such modifications must be made directly in Microsoft Partner Center. Fours keeps your listings in sync once your changes are published. See [Update an existing offer](https://learn.microsoft.com/en-us/partner-center/marketplace-offers/update-existing-offer) in the Microsoft documentation for full instructions. 1. **Log in to Microsoft Partner Center.** Go to [https://partner.microsoft.com/](https://partner.microsoft.com/) and sign in with your credentials. 2. **Open the Commercial Marketplace dashboard.** From the left-side menu, select **Marketplace offers**, then click the offer you want to edit. 3. **Choose the section to edit.** You can update various parts of your listing, including: - **Offer setup** — title, alias, categories. - **Properties** — plan names, SKUs. - **Listings** — marketing content, descriptions, icons, and documents. - **Technical configuration** — fulfillment URL, test plans. - **Pricing and availability**. 4. **Make changes and save.** Update the fields within each tab, ensure required fields are correctly filled, and click **Save draft** as you go. 5. **Submit for publishing.** Once all changes are made, go to the **Review and publish** tab, confirm all sections are complete, and click **Publish** to submit your updated listing for Microsoft's review. :::warning Once a product listing is live on Azure Marketplace, **pricing can only be changed once every 30 days**. ::: ## Change a Listing's Visibility To push your Azure listing to the public storefront or sunset an existing offer, work entirely within Microsoft Partner Center. - **Make a preview listing public** — See [Review and publish an offer](https://learn.microsoft.com/en-us/partner-center/marketplace-offers/review-publish-offer). - **Stop distribution of a live listing** — See [Stop distribution of an offer or plan](https://learn.microsoft.com/en-us/partner-center/marketplace-offers/update-existing-offer#stop-distribution-of-an-offer-or-plan). Fours picks the change up on its own — you don't set the status in the Console. Each hourly sync checks whether Azure reports the offer live in the store and reconciles the Fours product status: | Azure says | Current Fours status | Becomes | |---|---|---| | Live in the store | `UNLISTED`, `DRAFT`, `PENDING`, or `PENDING_CREATE` | `PUBLIC` | | Not in the store | `PUBLIC` | `UNLISTED` | | Either | `EDITED`, `DELETED`, or `UPDATE_FAILED` | Unchanged | So a listing you stop distributing in Partner Center moves to `UNLISTED` within the hour, and one you take live moves to `PUBLIC`. A product that was never public is not archived by this, and in-progress states are left alone. For more on why an older listing might have been stuck in `Draft`, see [How Fours reconciles the product status](/azure-marketplace/list-product/#how-fours-reconciles-the-product-status). --- Source: https://doc.fours.com/azure-marketplace/create-private-offer/ # Create Private Offer You can create and manage all of your Azure Marketplace private offers via Fours Console or API --- ## Overview Private offers let Independent Software Vendors (ISVs) and partners in the Cloud Solution Provider (CSP) program grow their revenue by creating time-bound customized margins that suit each entity’s business needs. As an ISV, you can specify the margin and duration to create a wholesale price for your CSP partner. When your partner makes a sale to a customer, Microsoft will make its payments to you off the wholesale price. There are two price types in the private offer you can select to customize the original price of the plans. They are [Discount Price](#discount-price) and [Absolute Price](#absolute-price). ### Discount Price Set a discounted percentage off based on the original price of the plan. For example below: - The `Plan for Growth` is type of [Flat Rate](/azure-marketplace/pricing-model/#flat-rate) pricing model. - Its original price is $499 per month + $0.01 per unit for extra usage of `support_unit`. - The private offer price on this plan is 7% off. So the final price after discount is $464.07 per month + $0.0093 per unit for the extra usage of `support_unit`. > Discount Price configuration example for a private offer plan ### Absolute Price Set an absolute price which is quite independent from the original price of the plan. For example below: - The `Plan for Enterprise` is type of [Flat Rate](/azure-marketplace/pricing-model/#flat-rate) pricing model. - Its original price is $1999 per month + $0.01 per unit for extra usage of `contract_unit` and $0.01 per unit for extra usage of `support_unit`. - The private offer on this plan is absolute price, which is $9 per month + $0.02 per unit for extra usage of `contract_unit` and $0.01 per unit for extra usage of `support_unit`. > Absolute Price configuration example for a private offer plan ## Prerequisites Before you start, make sure you have the following ready: - Buyer’s Azure billing account ID (see [Find Azure Billing Account ID](#find-azure-billing-account-id)) - The Azure product you want to sell - Agreed pricing terms (discount or absolute pricing) - Offer start and end dates ## The private offer lifecycle Creating and closing an Azure private offer spans both the Fours Console (seller) and the Azure portal (buyer). Because Azure separates the legal agreement from the financial transaction, the offer moves through several statuses before it becomes an active entitlement: 1. **Create the offer in Fours** — seller work in the Fours Console. 2. **Send the offer to your buyer** — share the offer link. 3. **Buyer accepts the offer** — status becomes `Accepted` with a `Pending Purchase` sub-status. 4. **Buyer completes the purchase in Azure** — the `Pending Purchase` sub-status clears. 5. **Activate the subscription** — an active entitlement is created in Fours. ### Step 1: Create the private offer in Fours In Fours Console, you can easily create Azure Marketplace private offers for your customers or CSP Partners. Click **New Private Offer** on the [Fours Console offer page](https://console.suger.io/offer), select the target Azure Product, and fill in the sections below. **Basic information** - **Offer Name**: The public-facing title of your private offer that the buyer sees when they review the agreement. Use a clear, consistent format such as `CustomerName - ProductName - MM-YYYY`. Azure allows up to **128** characters and does not accept `! < > ^ [ ] @ # % /`, control characters, the tilde `~`, or anything from U+007F to U+00FF — the non-breaking space, symbols such as `©` and `°`, and accented letters such as `é`. Characters beyond that range, such as `’`, `–`, `™` or CJK text, are accepted. The form checks the name as you type and names the first character Azure would reject and its position, which helps most with a pasted name whose offending character is invisible, such as a non-breaking space. - **Salesforce Opportunity / HubSpot Deal**: Optional fields that link this offer to an active deal in your CRM, so your sales team can track the offer's status (like `Pending_Acceptance` or `Accepted`) without leaving Salesforce or HubSpot. - **Customer Billing Account ID**: The exact Azure identifier for the buyer receiving the offer. This must be completely accurate, or the offer creation will fail. This offer is only available to the configured billing account, and the customer must be an owner, contributor, or signatory on it to accept. Customers can find their billing account by following the [guidance](#find-azure-billing-account-id) below. - **Description**: An internal notes field for your team's reference only — the buyer never sees this. Use it to track internal context, approvals, or deal notes. - **Prepared By**: The individual responsible for generating the offer. This typically auto-fills with your Fours login email. - **Contact(s)**: Optional. Pick people from your Fours contacts with **Add contact**, or add someone new with **Create new contact**. They are saved as the offer's contacts, and Fours emails them only through the **Offer Notification Contacts** rule in your [email notification settings](/settings/email-notification/#email-an-offers-contacts). They are not sent to Microsoft as the Azure offer's notification contacts. :::note Azure notification contacts are API-only The console form no longer sets the Azure offer's own **notification contacts** — the email addresses Microsoft sends status updates to. Only an offer created through the Fours API can still set `notificationContacts`, and Azure allows **at most 5** valid email addresses: a sixth, or an invalid address, fails the whole create with a **Create Offer Failed** status. Notification emails carried by a draft or a cloned offer are dropped when you submit it from the console. ::: **Offer terms** - **Expiry Date**: The deadline for your buyer. The offer expires after this date and the customer can no longer accept it. If they miss the deadline, you can extend this date later in the Fours Console without recreating the offer. - **Start Date**: The day the contract officially begins. You have two options: - *Accepted Date* — the contract uses the acceptance date as the start date, so billing and access begin as soon as the customer accepts it. - *Specific Month* — a future-dated option that sets the start date to the first day of the selected month. - **End Date**: The date the contract concludes. For Azure, the private offer ends on the last day of the selected month. **Pricing information** - **Offer Pricing Type**: Determines how you customize the buyer's cost. Selecting "price adjustment to your public plan" (also known as Discount Price or v1 pricing) applies a percentage discount to the standard storefront price. You can also set an [Absolute Price](#absolute-price) that is independent of the original plan price. - **Plan Pricing**: Use the dropdown to select the specific plan or tier you are selling (for example, your "Managed Application" or "Enterprise" plan), then enter the exact discount percentage or absolute price. Click **Add plan** to include multiple tiers in the same offer. > Plan Pricing section with plan selection and Add plan button - **Customer Renewals**: Indicate whether this deal is for a net-new or existing customer. Select **This is a renewal for an existing customer** if the buyer is extending a current Azure Marketplace contract or migrating an existing off-marketplace contract onto Azure. > ![azure_renewal.jpg](images/azure_renewal.jpg) **Custom contract duration** When you sell on a customized plan, you can set the contract duration yourself instead of taking a term published on the public plan. Microsoft's rules: | Unit | Allowed values | | ---- | -------------- | | Months | **1–120**, and **not a multiple of 12** | | Years | **1–10** | The value must be a whole positive number in either unit. A duration such as 24 months is rejected, because Microsoft expects the year unit for whole-year terms — enter **2 years** instead. Fours tells you which rule failed before the offer is submitted, for example: > A contract duration of 24 months is a multiple of 12 — use the year unit (2 years) instead. **Renewal behavior (SaaS only)** For SaaS offers on a customized plan, choose what happens when the contract term ends: - **Renew to private offer** — the subscription keeps renewing on the private-offer terms while the offer is active, then falls back to the public plan term you select. - **Renew to public offer** — the subscription renews directly onto the public plan term you select at the end of the current term. Both options need a public plan term to fall back to, so the renewal duration list offers only the terms actually published on the base public plan. If a duration you want is missing, publish that term on the public plan first. When you set a custom contract duration, Fours seeds the renewal settings for you rather than leaving them empty, because Microsoft rejects an offer on the current pricing schema that has none. The seeded defaults are: | Setting | Seeded value | | --- | --- | | Renewal behavior | **Renew to public offer** | | Renewal contract duration | The **shortest** term published on the base public plan | | Renewal billing frequency | The first frequency published for that duration | The renewal duration list is ordered shortest term first, so the default is always the least published term. If you want a longer renewal, or want the subscription to keep renewing on your negotiated pricing, change both fields before you submit — the seeded values are there to make the offer valid, not to express your intent. :::tip Check the Renewal Offer flag Fours marks an offer as a renewal when the Azure private offer carries Microsoft's customer-contract-renewal flag. If the **Renewal Offer** column reads **Yes** on an Azure offer, that offer renews an existing agreement rather than starting a new one. ::: **End User License Agreement (EULA)** Attach the legal terms for this offer: - **Standard Contract for Azure Marketplace**: Applies Microsoft’s default, pre-vetted legal terms to your deal. - **Use your own EULA**: Upload a custom PDF of your own legal terms or order forms. Use this when the standard marketplace terms lack the granularity you need, or when your order form contains detailed line items that differ from the high-level private offer total. Fields marked with an asterisk (*) are required, and which ones depends on your choices — a **Start Date**, for example, only when the contract starts on a *Specific Month* rather than the *Accepted Date*. **Create offer** stays greyed out while a required field is empty or a value isn't valid. To see what's left, hover over the button, or press Tab until it has focus: its tooltip, headed *Please complete:*, lists each step that still needs work and the fields in it — for example, *Step 2 Offer Terms — Expiry Date* — with the reason beside any value that isn't valid. A value that isn't valid is also outlined in red, with the reason beneath the field. Click **Create offer**. The offer status shows `In Progress` for a short time (up to ~15 minutes). Once processed, it changes to `Pending Acceptance` and is ready for the buyer to accept. ### Step 2: Send the private offer to your buyer Once the offer successfully pushes to Azure and reaches `Pending_Acceptance`, share the offer link with your buyer. 1. Go to the [**Offers**](https://console.suger.io/offer) page. 2. Find and open the offer, then click **Copy offer URL**. ![Copy offer URL in the Fours Console](images/create-an-azure-marketplace-private-offe-1.png) 3. Email this direct link to your buyer. The link acts as their checkout page to review the terms and accept the contract. ### Step 3: Buyer accepts the offer in Azure This step is completed by the buyer in Microsoft Azure. The buyer opens the private offer link from your sales team. To accept the offer, the buyer must have one of the following roles: - **Microsoft Customer Agreement (MCA)**: Billing Account Owner or Contributor - **Enterprise Agreement (EA)**: Enterprise Administrator Without the correct permissions, the buyer cannot proceed. See Microsoft's [Roles and permissions](https://learn.microsoft.com/en-us/marketplace/roles-permissions) for help confirming or setting up a role, and [Accept and purchase a private offer](https://learn.microsoft.com/en-us/marketplace/private-offers-accept-offer) for the full walkthrough. For buyer-facing acceptance guidance, see [Accept Private Offer](/azure-marketplace/accept-private-offer/). After acceptance, the Fours status changes to `Accepted` and a new `Pending Purchase` sub-status appears, meaning Azure still requires the buyer to complete checkout. ### Step 4: Buyer completes the purchase in Azure Because Azure separates the legal agreement from the financial transaction, the buyer must now officially subscribe to the product. 1. **Verify subscription permissions** — the user completing the purchase must have the **Subscription Owner** or **Subscription Contributor** role on the specific Azure subscription. See [Roles and permissions](https://learn.microsoft.com/en-us/marketplace/roles-permissions). 2. **Purchase and subscribe** — the buyer completes the purchase from the **Private Offer Management** dashboard in the Azure portal. See [Purchase and subscribe to the private offer](https://learn.microsoft.com/en-us/marketplace/private-offers-purchase) for the full walkthrough. :::info If the buyer already has both accept and purchase permissions, the option to complete the purchase appears on the same page right after acceptance. A quick browser refresh on the **Private Offer Management** dashboard is all they need to proceed. ::: Once the purchase is complete, the `Pending Purchase` sub-status clears and the entitlement becomes active. ### Step 5: Activate the subscription in Fours This step completes the setup and makes the deal fully active. 1. **Configure account in Azure** — after checkout, the buyer clicks **Configure Account Now** in Azure. 2. **Complete software provisioning** — the buyer is redirected to your software’s signup page to create or link their account. 3. **Activate entitlement in Fours** — once setup is complete, the `Pending Purchase` sub-status is cleared and an active **Entitlement** is automatically created. The deal is now fully live and ready for billing. ### Extend the expiry date If the buyer needs more time, extend the offer instead of recreating it. Open the offer in the Fours Console and use **Extend Expiry Date**. The action is available when both of these hold: - The offer's status is **`Pending Acceptance`**, **`Expired`**, or **`Update Failed`**. An offer that already expired can still be revived this way. - The offer was priced as **new customized plans** (SaaS or otherwise) or as **VM software reservations**. Offers built as a price adjustment to an existing plan cannot be extended — Azure rejects the extension as conflicting with the existing private offer for the same billing account and products. Clone the offer onto a customized plan instead. The new date must be **after today** and **after the current expiry date**. If the offer has a future start date, the new expiry must also fall **before** that start date. The date picker enforces all three and tells you which one you missed, for example `New expiry date must be after current expiry date (2026-03-01)`. ### Creating a Private Offer With Flexible Billing Schedule Flexible billing is now supported for Private Offers and can be easily configured directly in the Fours Console. To create a flexible billing schedule, navigate to “New Private Offer,” select your Azure product, set an absolute price, and choose a billing frequency. You can opt to bill immediately or delay the first charge to a future date. The feature allows you to establish a payment schedule with up to 70 installments over the selected contract duration. Each installment requires a unique charge date and amount, with the option to include notes for added clarity. :::warning Flexible billing needs a new customized plan Two rules decide whether flexible billing is available: - A **flexible** billing frequency and a flexible payment schedule go together. Selecting the frequency without building the schedule (or the reverse) is rejected. - Flexible billing is **not supported when you only adjust the pricing of an existing plan**. If you build the offer as a price adjustment to a published plan, the create fails with `flexible billing is NOT supported for 'editExistingOfferPricingOnly'`. Create the offer with **new customized plans** instead — that is the pricing type flexible schedules are built on. ::: >![create-flexible.jpg](images/create-flexible.jpg) Here’s an example of a flexible payment schedule with five installments spread over a two-year contract period: | Charge Date | Amount (in USD) | Notes | |-------------------------------|-----------------|-------------------| | Immediate charge when billing starts | $0.00 | No immediate fees | | Jan 10, 2026 | $5,000.00 | First charge | | Jul 05, 2026 | $2,500.00 | Mid-year charge | | Mar 15, 2027 | $8,000.00 | Q1 charge – year 2| | Sep 20, 2027 | $4,000.00 | Final charge | | **Total amount (in USD)** | **$19,500.00** | | #### Immediate Charge When Billing Starts The immediate charge is the first payment processed when billing begins, with its charge date matching the contract start date. In the Fours Console, you can set this amount to zero USD if no upfront payment is required, or specify a value to collect an initial fee upon subscription activation. #### Charge Dates (UTC) Each installment after the immediate charge requires a unique charge date in UTC time zone, which is when the transaction is executed and recorded. In the Fours Console, these dates must fall within the contract duration. For example, if a private offer starts on July 01, 2025, with a two-year duration, all charge dates must be between July 01, 2025, and June 30, 2027. If the offer starts on a specific month, dates must align from the first day of that month. Overdue charges due to subscription delays are billed immediately once billing starts. #### Amount The amount for each installment can be set in the Fours Console, ranging from zero USD to a maximum of 100,000,000 USD. ## Creating Private Offer For Azure VM Product This addendum outlines the key differences and configuration requirements when creating a **Private Offer for a Virtual Machine (VM) product**, supplementing the general Private Offer creation documentation. --- ### Focus on VM Product Selection When starting the Private Offer creation process, the first important step is selecting the correct **product type**, as this determines the pricing model and available configuration fields. #### **Target Product** - In the **Product** field, select a product classified as **VM (Virtual Machine)**. > ![The Product field on the private-offer form with a VM (Virtual Machine) product selected, which is what loads the VM-specific pricing plans](images/vm-product.jpg) #### **VM Plans** - Choosing a VM product loads **VM-specific pricing plans**, commonly based on: - VM core sizes - Management or deployment models --- ### Specific Pricing for VM Reservations For VM products, the **Pricing Information** section focuses on **VM software reservations**. - **Only one pricing method is supported:** **Create a private offer with absolute pricing as a new VM software reservations plan. (V3 pricing)** > ![The Pricing Information section for a VM product, offering the single supported method — absolute pricing as a new VM software reservations plan (V3 pricing)](images/pricing-information.jpg) ### Contract Duration and Billing Frequency For VM reservation plans, both **contract duration** and **billing frequency** are required fields. #### **Contract Duration** Defines the customer's commitment term: - **1-year** - **3-year** #### **Billing Frequency** - **Upfront**: Customer pays the entire contract amount in a single payment at the beginning of the term - **Monthly**: Payment is divided into equal monthly installments throughout the contract duration - **Flexible schedule**: Allows you to create a custom payment schedule with specific charge dates and amounts (up to 70 installments) A VM reservation must carry exactly one of these three payment schedules — Azure's schema accepts only `month`, `year`, or `flexible`. **Upfront** is the `year` schedule, and its value has to match the reservation duration in years, so a 3-year upfront reservation is `year: 3`, not `year: 1`. > ![The VM plan pricing configuration in the Fours Console — the Contract Duration selector (1-year or 3-year) beside the Billing Frequency choice of Upfront, Monthly, or Flexible schedule](images/vm_plan_settings.png) *The screenshot above shows the VM plan pricing configuration interface in Fours Console, where you can select both the Contract Duration (1-year or 3-year) and Billing Frequency (Upfront, Monthly, or Flexible schedule) for your VM software reservation plan.* ### Summary For VM offer Creating a Private Offer for Azure VM products requires specific configurations that differ from standard SaaS or other product types. Unlike regular private offers that support both discount percentage and absolute pricing, **VM Private Offers exclusively use the V3 pricing model** with absolute pricing for VM software reservations. When configuring an Azure VM Private Offer, you must carefully review and populate the following required fields: - **VM Plan Selection**: Choose the appropriate VM-specific pricing plan based on your customer's needs. These plans are typically structured around VM core sizes and deployment models. The selected plan determines the foundation for your reservation pricing. - **Reservation Price Type**: VM products support only one pricing method - **absolute pricing as a new VM software reservations plan (V3 pricing)**. Discount percentage pricing is not available for VM products. This absolute pricing model allows you to set a completely custom price independent of the original plan pricing. - **Contract Duration**: Specify the customer's commitment term for the VM software reservation. You must select either a **1-year** or **3-year** duration. This is a mandatory field that defines the total length of the reservation period. - **Billing Frequency**: Determine how your customer will be charged throughout the contract duration. Available options include: - **Upfront**: Single payment at the start of the contract - **Monthly**: Recurring monthly payments throughout the contract period - **Flexible schedule**: Custom payment schedule with up to 70 installments, allowing you to define specific charge dates and amounts All four of these settings work together to ensure compliance with the Azure VM software reservation model and must be configured correctly for successful private offer creation and acceptance. ## Auto-Activation When your Azure integration has [**Self-Managed Subscription Activation**](/azure-marketplace/integration/) turned on, the private offer form carries a per-offer **Auto-Activation** toggle — *Automatically activate the subscription on purchase*: - **On** — Azure activates the SaaS subscription automatically once the customer purchases this private offer. - **Off** (the default) — your team activates the subscription. Fours does not, because that integration manages subscription activation itself. The toggle appears only on **V2 pricing** (`newCustomizedPlans`). A V1 offer cannot carry the setting, so it is hidden rather than shown disabled. ## Fours API You can also create Azure Marketplace private offers programmatically with the [Fours API](/api/). For more detailed guidance, email [support@suger.io](mailto:support@suger.io). ## Troubleshoot There are two common failure errors when creating azure private offer. 1. **Reusing a private offer name**. A private offer name cannot be reused while another offer still holds it. Fours checks this before submitting, and the error names the offer that is blocking you. Only four statuses release a name — an offer that either never reached Azure or was never live: | Status | Why it does not block | | ------ | --------------------- | | `CREATE_FAILED` | Never reached Azure. | | `INVALID` | Never reached Azure. | | `DELETED` | Never live. | | `REJECTED` | Never live. | Every other status blocks, **including `EXPIRED`, `DEPRECATED` and the cancelled statuses**. Azure does not release a promotion name when the offer expires or is deprecated — the old offer still owns the name on the publisher — so re-using it would fail at the Azure create call with a non-retryable conflict. Fours surfaces it as a validation error in the form instead. An offer never conflicts with **itself**, so re-submitting or editing a saved offer that keeps its own name is always allowed. A draft that exists only in Microsoft Partner Center — one started there and never published — also holds its name. When your offer's name matches such a draft, the error names the draft and asks you to rename your offer (for example, by adding a version suffix) or delete the draft in Partner Center. :::tip Solution - use a different offer name and re-create the private offer. - if the name belongs to a draft in Partner Center that you no longer need, delete that draft in Partner Center. ::: 2. **Duplicate offers for SAME product and price plan**. A new private offer cannot be created if a previous offer exists with the **same** product and price plan for the **same** Azure billing account ID. :::tip Solution - If the previous offer has been accepted or purchased, there are two options: * Wait for the end of previous offer, and create new offer based on the same product & price plan. * Create new offer based on the same product but different (or new) price plan - If the previous offer has not been accepted, cancel it and create new one. ::: ### Reading a failed offer's error message When Microsoft refuses an offer, the raw response is a nested API error — a code, a message, and a stack of wrapping from the systems that carried it. Fours rewrites the ones Microsoft documents into a plain sentence and stores it on the offer, so the offer detail page shows something you can act on rather than something you have to decode. Microsoft sometimes returns a code with no message at all. Fours expands those into their documented meaning: | Microsoft error code | What it means | | --- | --- | | `businessValidationError` | The offer did not pass one of Microsoft's validation checks | | `collectionLimitExceeded` | A limit on the number of items was exceeded | | `invalidId` | One of the IDs in the request is not valid | | `invalidEntityStatus` | The item's status does not allow this request | | `invalidRequest` | The request is not valid | | `invalidResource` | One of the items in the request is not valid | | `invalidState` | The item's current state does not allow this request | | `notDeployed` | The item has not been deployed | | `notSupported` | This operation is not supported | | `operationCanceled` | The operation was canceled | | `productLocked` | The product is locked right now | | `resourceNotFound` | Something referenced by the request could not be found | An error Microsoft does not document is left as it came, so nothing is lost in translation — quote it to [support@suger.io](mailto:support@suger.io) if it is not self-explanatory. ## Find Azure Billing Account ID 1. Sign in to the [Azure portal](https://portal.azure.com/) 2. Search for and select Cost Management + Billing. 3. If you have access to just one billing scope, select Properties from the left menu (inside `Settings`). Otherwise, click `Billing Scopes` on the left menu and select one billing scope. 4. The Azure Billing Account ID can be found in the red box as shown below. > Azure Billing Account ID highlighted in the Azure portal ## FAQ For private offer ### Can I cancel an offer directly from Fours using this button? An offer auto-renewed because the customer did not turn off the auto-renewal function, and now we need to cancel and refund it. Is it better to do this from the Azure platform? There is no cancel button on the Microsoft partner center. Yes, you can cancel it on the Fours console by clicking the Cancel Button; you must cancel the entitlement instead of the offer. ### Do I need the client's Azure ID to create the Fours offer? You'll need their Azure Billing ID to submit the private offer. Here is how to find it: [https://www.youtube.com/watch?v=Pv0U58sZdJ4&ab\_channel=MicrosoftReactor](https://www.youtube.com/watch?v=Pv0U58sZdJ4&ab_channel=MicrosoftReactor) ### A customer accepted and purchased our product, but our dashboard does not reflect it. The offer has been accepted and purchased. The error is because when the entitlement is created, we first don’t know (Azure doesn’t tell us) which private offer has been purchased. The entitlement is connected to the private offer later (it may take a few hours via the Azure marketplace CMA report sync) ### The EULA I attached to the offer needs adjustments. How can I do that? The best option is to cancel the existing offer and create a new one. It's not possible to edit an ongoing offer. ## FAQ For Flexible Billing ### Can I set different billing frequencies for multiple plans within the same private offer? Each plan in a private offer has its own billing frequency. To align multiple plans with the same billing schedule, ensure that the charge dates for each plan are configured identically when setting up the pricing in the Fours Console. ### Can I modify a flexible billing schedule after creating the private offer but before the customer accepts it? Yes, you can modify the flexible billing schedule in the Fours Console before the customer accepts the offer. However, once the offer is accepted, the schedule is locked and cannot be changed. To make changes post-acceptance, you would need to cancel the subscription and create a new private offer. ### What happens to a flexible billing schedule when a private offer expires? Once a customer purchases the plans in a private offer, the flexible billing schedule is locked for the full contract duration, even if the private offer expires. The expiration of the offer only affects the ability to purchase the plans at the custom price, not the ongoing subscription charges. ### Can I set an immediate charge for a flexible billing schedule? Yes, you can define an immediate charge that is transacted as soon as billing starts, with the charge date matching the contract start date. You can set this amount to zero USD if no immediate charge is desired. ### Can I use flexible billing for contract durations shorter than one year? No, flexible billing schedules are supported only for contract durations of 1, 2, or 3 years. Custom durations such as 9 months or 19 months are not supported. ### Can I offer products with quarterly billing options to customers? Yes, using the Fours Console, you can create a flexible billing schedule specifying dates and amounts to be charged, allowing you to set quarterly billing for one or more plans. ### What is the maximum number of installments allowed in a flexible billing schedule? You can configure up to 70 installments for a flexible billing schedule, each with a unique charge date and amount, within a contract duration of 1, 2, or 3 years. Custom durations shorter than one year, such as 9 months or 19 months, are not supported. ### How will flexible billing apply for metered billing, when future usage cost is unknown? For SaaS plans with metered billing, you can offer a flexible schedule for the base flat-rate price only. The Metered usage or overage charges will be calculated and billed separately each month. ### Will the same flexible billing schedule automatically apply to subscription renewals, and how should I handle renewals as a vendor? No, flexible billing schedules are highly customized and do not automatically apply to subscription renewals. Customers may have recurring billing enabled, which could lead to renewals at standard rates, so it’s advisable to coordinate with your customer to disable auto-renewal at purchase to avoid unintended renewals. As a vendor, you should proactively engage with your customer before the contract ends to create and offer a new private offer with a tailored flexible billing schedule for continued usage, ensuring alignment with their needs and your sales strategy. --- Source: https://doc.fours.com/azure-marketplace/accept-private-offer/ # Accept Private Offer Guidance to accept the private offer as the end buyer in Azure marketplace --- ## Overview This guide provides step-by-step instructions on how to accept a private offer on Azure marketplace. It explains the process of reviewing and accepting the offer, checking the start and end dates, and understanding the usage metrics. It also guides users through the signup process. ## Before you begin To accept a private offer on the Microsoft commercial marketplace, the buyer must meet the following prerequisites: - The [`Enterprise Agreement Admin`](https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/understand-ea-roles) or [`Billing Account Owner`](https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/understand-mca-roles#billing-role-definitions) role is required to accept the private offer terms. - Holding the [`Owner` or `Contributor`](https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal-subscription-admin) role in the organization's main Azure Account on the subscription (not Marketplace account) is essential to subscribe to the private offer. - The buyer needs to be logged into the Azure account designated in the private offer. - The Microsoft private offer should be based on a public plan that is available in the buyer's market. When creating a private offer, verify the market location of the buyer's billing account and select the appropriate market. :::danger - There are two actions required to procure a private offer: [accept](#accept-private-offer) and [purchase](#purchase-private-offer). The person accepting the private offer and the person purchasing the private offer require different permissions, depending on the agreement type. The person purchasing the private offer can use the [private offer eligibility report](https://learn.microsoft.com/en-us/marketplace/private-offers-pre-check) to check if they have the correct permissions. ::: The permissions required to accept and purchase are summarized in the following table: > | Agreement type | Permissions to accept offer | Permissions to purchase or subscribe | > | :----------- | :---------- | :---------- | > | Microsoft Customer Agreement (MCA) | [Billing account owner or contributor](https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/understand-mca-roles#billing-role-definitions) | [Subscription owner or subscription contributor](https://learn.microsoft.com/en-us/azure/role-based-access-control/rbac-and-directory-admin-roles#azure-roles) | > | Enterprise Agreement (EA) | [Enterprise administrator](https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/understand-ea-roles) | [Subscription owner or subscription contributor](https://learn.microsoft.com/en-us/azure/role-based-access-control/rbac-and-directory-admin-roles#azure-roles) | ## Accept private offer Once you complete any necessary prechecks, check permissions, and have your [billing account ID](https://learn.microsoft.com/en-us/marketplace/private-offers-in-azure-marketplace#find-billing-account-id) ready, you're ready to accept a private offer. The buyer can navigate to the private offer by clicking the **private offer link** from the Fours notification email or sales representative. Accepting the private offer means you agree to the terms and prices listed in the offer, creating a contractual agreement between your organization and the Microsoft partner. Accepting the private offer agreement includes: - Legal entity name to which the offer applies - Plans included in the offer - Private offer price - Custom legal terms for the offer, if applicable - Start and end dates when the negotiated price applies to this offer - Expiration date for the offer; you must accept the offer before this date :::danger - In case the **private offer link** is not accessible, buyers can also go to their [Azure Portal](https://portal.azure.com/), click **Marketplace**, then click [Private Offer Management](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/PrivateOffersCenter.ReactView) and select the offer there. ::: ## Purchase private offer If you [accept the private offer](#accept-private-offer) using the **private offer link**, you're redirected to the Azure portal to complete the purchase on the private offer management dashboard. Alternatively, you can also find the private offer by logging into the Azure portal and select the [private offers management](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/PrivateOffersCenter.ReactView) dashboard in the marketplace. To complete the purchase of your private offer, follow these steps: 1. In the Azure portal, access the marketplace. You can search for marketplace in the search bar in Azure and select the marketplace icon. Select [private offers management](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/PrivateOffersCenter.ReactView). 2. Under private offer management is a list of all the private offers with their status. 3. To purchase the private offer, select **Purchase**. 4. Click **Review and Subscribe**, and review the configured private offer. 5. Click **Subscribe**. 6. When the subscription process completes, click **Configure Account Now**. 7. Complete the sign up form so that the ISV can provision the software. ## What gets created in Fours (For Sellers) Once the buyer completes the purchase, Fours creates the entitlements from Microsoft's order data. **One entitlement per subscription, not per order.** An Azure entitlement is identified by the subscription's asset — not by the order that produced it. For SaaS and Azure application products the two are the same thing, so nothing changes for those. It matters for the rest: - **Virtual machines** — an order covering two VMs produces **two entitlements**, one per VM subscription, each metered and renewed on its own. - **Professional services** — these now produce entitlements at all. Previously an accepted professional-services order created none. If you reconcile against Microsoft, match on the subscription (asset) rather than the order reference, and expect the entitlement count to follow subscriptions. ### Entitlement status follows the order status Fours maps Microsoft's order status onto the entitlement lifecycle: | Azure order status | Entitlement status | Meaning | | --- | --- | --- | | `active` | Active | The subscription is running normally. | | `warning` | **Suspended** | The subscription's payment failed and Azure has put it in dunning. It is still live — not cancelled. | | `expired` | Cancelled | The term ran out. | | `canceled` / `cancelled` | Cancelled | The customer cancelled the subscription. | | `abandoned` | *(unchanged)* | Fulfillment never completed, so Fours does not create an entitlement and does not retro-cancel one that exists. | The `warning` status is the one worth watching. A suspended entitlement is a paying customer whose card or invoice failed, not a churned one — chase the payment rather than the renewal. ## Understanding Offer Sub-Status (For Sellers) When monitoring offers in your Fours Console, you may notice a sub-status field that provides additional context about accepted offers. The sub-status helps sellers understand the current state of an offer beyond the main status. ### Pending Purchase Sub-Status An offer may show a `pending_purchase` sub-status when the following conditions are met: - The offer status is **accepted** - No entitlements have been created yet **What this means**: As documented in the [two-step process](#accept-private-offer) above, Azure private offers require both acceptance and purchase actions. The `pending_purchase` sub-status indicates that the buyer has accepted the offer terms (creating the contractual agreement) but has not yet completed the purchase step to activate the subscription. This is a normal intermediate state in the Azure offer lifecycle. The buyer may be: - Preparing to complete the purchase configuration - Coordinating with their team who has different permissions for purchasing - Waiting for internal approval to proceed with the purchase **Automatic clearing**: The sub-status is automatically cleared when entitlements are created, which happens once the buyer completes the purchase step in the Azure portal. If an offer remains in this state for an extended period, you may want to follow up with the buyer to ensure they complete the purchase process. --- Source: https://doc.fours.com/azure-marketplace/cppo/ # CPPO Create and manage Azure Marketplace Channel Partner Private Offer (CPPO) in Fours --- ## Overview The CPPO (Channel Partner Private Offer) is a sales model offered by Azure cloud platforms, allowing Independent Software Vendors (ISVs) to sell their software or services through channel partners. There are two types of CPPO. **The CSP Partner Private Offer** (also known as margin sharing) is a private offer type that is designed to motivate eligible partners to sell an ISV's solution. ISVs can make private offers and extend a margin to partners in the Cloud Solution Provider program (CSPs). **The Multiparty Private Offer** enables multiple partners, including ISVs and other resellers, to collaborate and create a unified custom offer for a customer. ### Key terms - [**CSP Partner Private Offer**](https://learn.microsoft.com/en-us/partner-center/marketplace-offers/isv-csp-reseller) — A private offer where a Cloud Solution Provider (CSP) partner works with an ISV to resell a product to a buyer through Azure Marketplace. - [**Multiparty Private Offer (MPO)**](https://learn.microsoft.com/en-us/partner-center/marketplace-offers/multiparty-private-offers-for-isvs) — A private offer in Azure Marketplace that involves an ISV and a channel partner selling jointly to a buyer. - **Resale Authorization** — A configuration in Fours (`CPPO_OUT`) that allows a channel partner to resell a product. It defines pricing, terms, and allowed plans. - **ISV (Independent Software Vendor)** — The company that owns and publishes the product in Azure Marketplace. - **Channel Partner (Reseller)** — The partner who sells the ISV's product to the buyer and creates the final private offer. | Comparison | Multiparty private offers | Private offers with CSP margin-sharing | | ----------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | Target audience | ISV partners, Partners in the Cloud Solution Provider program (CSPs) | ISV partners, Partners in the Cloud Solution Provider program (CSPs) | | Target customers | Primarily aimed at **large enterprise customers** with an enterprise agreement (EA) or Microsoft Customer Agreement (MCA). | Designed to help ISVs reach **small and medium-sized businesses (SMBs)** by leveraging CSPs. | | Pricing | Pricing is negotiated between ISVs and partners as part of the collaboration. | The CSP partner has full control over the pricing strategy and customer relationship, giving them more autonomy in the sales process. | | Billing | Microsoft bills to customers | CSP partners bill to customers | | Availability | Available today for customers purchasing in the United States, United Kingdom, and Canada. | Avaliable | | Customer MACC decrement for eligible apps | Yes | No | | Channel partner participation | Partners enrolled in the Microsoft AI Cloud Partner Program and enrolled in the [commercial marketplace](https://learn.microsoft.com/en-us/partner-center/account-settings/create-account) with United States or United Kingdom tax profiles for marketplace in Partner Center. ISV partner sends a private offer to the partner. | [CSP program enrolled partners](https://learn.microsoft.com/en-us/partner-center/enrolling-in-the-csp-program) only. ISV sends a private offer to CSP. | ## Prerequisites Before you can create a Resale Authorization, both the ISV and Channel Partner must complete a few Azure Marketplace and Fours setup requirements. If any of these are missing, you won't be able to proceed. **Azure Marketplace** - **Enroll in required programs.** You and your channel partner must be enrolled in: - Microsoft AI Cloud Partner Program - Commercial Marketplace - Cloud Solution Provider (CSP) program (for margin-sharing deals) - **Complete account setup.** Both parties must have fully completed their legal profile, payout details, and tax information in Partner Center. - **Meet marketplace eligibility.** Your Azure product must be approved and available in the marketplace. **Fours** You need **Admin** access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). ## CSP Partner Private Offer The **CSP Partner Private Offer** process involves ISVs working with a specific CSP partner to provide personalized offers to customers, with the CSP partner managing customer relationships, pricing, and value-added services. ### Create a private offer for a CSP partner In Fours Console, you can easily create the CSP partner private offers for your CSP Partners. Click the button of `New Resale Authorization` in the [Fours console offer page](https://console.suger.io/offer), select the target Azure Product, choose the private offer type `Private offers with CSP margin-sharing` and fulfill the info listed as below: - **CSP Partners**: The CSP partners you authorize to sell your private offer. - Search for your partners by name/tenantID and choose from the results. - If the target partner is not in the search results, enter their ID. - **Optional**: To extend a private offer to individual customers of a CSP partner, choose All customers selected for that CSP partner. ![csp_partners](https://imagedelivery.net/pNNvR2_tZYczcQ3leBU_1A/0ded20ae-ba32-4203-70fb-78127fb97e00/public) - **Start Date**: There are two options to set the start date of the private offer once it is accepted. One is applying the accepted date as the start date. The other is to specify the start date - the first day of the selected month. - **End Date**: The private offer will end on the last day of the selected month. - **Notification Contacts**: Provide up to five emails as Notification Contacts to receive email updates on the status of your private offer. - **Pricing**: Configure the percentage-based margins for up to 10 plans in a private offer. The margin the CSP partner receives is a percentage off your plan's list price in the marketplace. ![csp_offer_pricing](https://imagedelivery.net/pNNvR2_tZYczcQ3leBU_1A/955a8a0f-052f-418a-9d3f-ca1876e5ae00/public) ## Multiparty Private Offer In Azure, the process for ISVs to create a **Multiparty Private Offer** focuses on collaboration with multiple partners, such as other ISVs or channel partners, to create a customized joint offer. Microsoft handles billing and payments for customers. ### Create multiparty private offer In Fours Console, you can easily create the **Multiparty Private Offer**. Click the button of `New Resale Authorization` in the [Fours console offer page](https://console.suger.io/offer), select the target Azure Product, choose the private offer type `Multiparty private offers` and fulfill the info listed as below: - **Partner's seller ID**: Enter the marketplace seller ID of your partner. Your partner can locate this information in Partner Center under Account settings > Identifiers > Publisher within their organizational profile. - **Customer billing account ID**: Specify the billing account for the customer receiving this multiparty private offer. The multiparty private offer will only be available to the configured customer billing account. The customer must be an owner, contributor, or signatory on the billing account to accept the offer. - **Start Date**: There are two options to set the start date of the private offer once it is accepted. One is applying the accepted date as the start date. The other is to specify the start date - the first day of the selected month. - **End Date**: The private offer will end on the last day of the selected month. - **Expiry Date**: Your offer will expire after this date and your customer will not be able to accept it. - **Notification Contacts**: Optionally provide up to five email addresses for the people within your company as Notification contacts to receive email updates on the status of the multiparty private offer. - **Pricing**: Configure the discount % off or absolute price for one or multiple plans in a private offer. ![multiparty_private_offer_pricing](https://imagedelivery.net/pNNvR2_tZYczcQ3leBU_1A/a98fe7f7-342e-40c5-a71a-4e2a80115500/public) ## Create a Resale Authorization You can also create a Resale Authorization (`CPPO_OUT`) from the **Resale** page, which walks you through basic information, offer terms, pricing, and other details in a single flow. 1. **Open the Resale Authorization flow.** 1. Go to the **Resale** page in the [Fours Console](https://console.suger.io/resale/sent). 2. Click **+ New Resale Authorization** in the upper-right corner. 3. Select the **Azure Product** you want to use. This defines what the Channel Partner is allowed to resell. 2. **Add basic information.** 1. Enter an **Offer Name** to identify the resale authorization. For a **Multiparty private offer** or a **Private offer with CSP margin-sharing** (the types in step 4), the name must follow Azure's [private offer naming rule](/azure-marketplace/create-private-offer/#step-1-create-the-private-offer-in-fours), and the form flags any character Azure would reject. A **Resale authorization**'s name is not checked against that rule. 2. (Optional) Link a **Salesforce Opportunity** to associate the authorization with a CRM opportunity. 3. (Optional) Link a **HubSpot Deal** to associate the authorization with a HubSpot record. 4. Select the **Private Offer Type** to define the type of resale authorization being created: | Type | What it is | | ---- | ---------- | | **Multiparty private offer** | You and a channel partner jointly price a deal for one named end customer. | | **Private offer with CSP margin-sharing** | You extend a margin to motivate Cloud Solution Provider partners to sell your solution, so CSPs can package it with their own software and services. | | **Resale authorization** | You authorize a resale partner to sell this product on your behalf in the **customer markets you choose**. The partner then creates their own private offers for it in Partner Center. Offered only for SaaS products (including Flat Rate and Per User) and virtual machine products; a container product offers **Multiparty private offer** only. A draft that already holds a resale authorization keeps the option. | :::note **A resale authorization is a standing grant, not a private offer.** It has no pricing, no dates and no terms of its own, and you can revoke it at any time. It needs only the **resale partner's seller ID** and **at least one customer market** — the offer-terms and pricing steps below do not apply to it. To revoke one, open the resale authorization and click **Cancel**. It shows `Pending Cancel` while Microsoft processes the revocation, and it can't be cancelled again until that finishes; then it moves to `Cancel Success`. If Microsoft refuses the revocation, the authorization goes back to `Active` and its page shows a **Revoke Authorization Failed** alert with Microsoft's reason — you can click **Cancel** again. Once created, its record shows two fields the other two types do not have: **Customer Markets** (where the partner may sell) and **Authorization Status**. **Customer Markets** lists only the markets where Microsoft supports resale. Brazil (BR), Belarus (BY), India (IN), South Korea (KR), Mexico (MX), Russia (RU) and Singapore (SG) are not offered, because Partner Center rejects an authorization that includes any of them. If you reopen a saved draft that still names one of these markets, Fours drops it so the draft can be submitted. ::: 5. Add the **Partner seller ID** to identify the channel partner involved in the authorization. 6. Add the **Customer billing account ID** to define the billing account for the end customer. 7. (Optional) Add a **Description** to include additional context about the authorization. 3. **Define offer terms.** 1. Set the **Expiry Date** by which the reseller must use the authorization. 2. Determine when the authorization becomes active by choosing a **Start Date** type. 3. Set the **End Date** by which the authorization stops being valid, even if it hasn't been fully used. 4. **Set pricing information.** 1. Select the **Offer Pricing Type** to define how pricing is structured. 2. Select a **Plan** to choose the product plan used for the authorization. 3. Click **Add plan** to include additional plans in the authorization. 5. **Add other information.** 1. Set **Customer Renewal** to define whether this authorization is for an existing customer renewal or a new customer. 2. Choose an **EULA** to define the legal terms shown to the end customer. 3. (Optional) Add **Internal Notes** to include internal context or comments. 6. Click **Create offer**. It stays greyed out while a required field — marked with an asterisk (*) — is empty or a value isn't valid; hover over it, or press Tab until it has focus, to see what's left. ### Name your terms document carefully Azure's ingestion API validates the name of every terms-and-conditions document, and it is stricter than the upload that accepted the file. Fours repairs a non-conforming name automatically so the authorization is not rejected — but the repaired name is what the buyer sees on a legal agreement, and the original is not recoverable afterwards. The upload control gives no warning before a rewrite, so it is worth naming the file well the first time. | Constraint | Limit | | ---------- | ----- | | File name | Up to **128** characters | | Customer-facing document name | Up to **100** characters | | Characters | Printable ASCII only. Anything else becomes `_`; non-ASCII spaces become a plain space. | | Ending | Cannot end in `!`, `>`, `^`, `[`, `@`, `#`, `%`, or `/` | | Minimum | At least 2 characters | When truncating a file name Fours keeps the extension, so `.pdf` survives. A name that cannot be repaired at all falls back to `TERMS_AND_CONDITIONS.pdf` and the display name to `Terms and Conditions`. A safe name is plain ASCII, under 100 characters, and ends in a letter or `.pdf` — for example `Acme-Corp-Reseller-Terms-2026.pdf`. :::info Where this applies Name repair runs on **Azure resale authorization (`CPPO_OUT`) creates**, on **extending an authorization's expiry date**, and on **deleting one**. Regular Azure private offers are deliberately left alone, so their document names reach Azure exactly as you set them. ::: ## Hand off to the Channel Partner Once your resale authorization becomes `Active`, the Channel Partner takes ownership of creating the final private offer. At this stage, you (the ISV) can't build the offer for them, but you must initiate the handoff and monitor the deal's progress. 1. **Notify the Channel Partner.** 1. Open the active authorization in the Fours Console. 2. Click **More actions** in the top-right corner, and select **Notify Contact**. This automatically sends the reseller an email with a direct link to the authorization, letting them know it's ready to use. 2. **Coordinate deal details.** Work with your partner to confirm you have the correct **Customer Billing Account ID**, as Azure strictly requires this to route the offer to the correct customer. Align on the timing for when the final offer will be sent to the buyer. ## Track buyer acceptance and entitlements After the reseller generates the private offer, you won't see their final markup, but you can oversee the entire deal lifecycle directly in the Fours Console. Azure follows a unique two-step purchase flow, which Fours tracks automatically. ### Track your partner's progress If you created a multiparty offer, your authorization will display a **Pending Partner Action** status while it awaits the partner's review and configuration in the Microsoft Partner Center. ### Monitor the new private offer (`CPPO`) Once the reseller successfully sends the private offer to the end buyer, a new deal entry will appear automatically with the type **CPPO** and a **Pending Acceptance** status. ### Understand Azure's two-step checkout (`Pending Purchase`) The buyer must first review and accept the terms, which changes the offer status to **Accepted**. However, Azure requires a final subscription step to finish the purchase. During this gap, Fours displays a **Pending Purchase** sub-status. If an offer sits in this status for too long, it means the buyer has not completed checkout in Azure yet. ### Manage active entitlements Once the buyer completes the final subscription in Azure, Fours automatically generates a **CPPO Entitlement**. This confirms the purchase is fully completed and serves as your authoritative record of the active contract. --- Source: https://doc.fours.com/azure-marketplace/revenue/ # Revenue Track billed revenue, marketplace fees, and payouts from your Azure Marketplace subscriptions in Fours. --- ## Overview Microsoft handles billing on its side — it invoices your customers, deducts its marketplace fee, and pays out your earnings. Fours does **not** process Azure payments. Instead, Fours **ingests** the billing data Microsoft publishes through **Commercial Marketplace Analytics** (Partner Center) and normalizes it into unified **revenue records**, so Azure revenue sits alongside your AWS, GCP, and Snowflake revenue in one place. Fours syncs two datasets from Partner Center: | Dataset | Source | What it contains | |---------|--------|------------------| | **Revenue** | Commercial Marketplace Analytics revenue report | One row per purchase line — estimated (gross) revenue and your earning (net) amount, invoice status, and reseller. | | **Earnings** | Transaction history / earnings export | The payout status and payment-sent date for each earning, used to record disbursements. | Fours joins the two and resolves each purchase to the matching Fours buyer, product, and entitlement where possible. ## Where to find Azure revenue Azure is a first-class channel in Fours' revenue surfaces: 1. Open **Revenue → Revenue Records**. 2. Set the **Channel** filter to **Azure**. Two tabs are available: - **Joined Records** — one normalized row per purchase, with billed amount, marketplace fee, collectable amount, and disbursement. - **Raw Records** — the source revenue rows exactly as Commercial Marketplace Analytics reported them. You can also see Azure revenue for a single **buyer** on its detail page, or for a single **entitlement** on its detail view. See the [Revenue Records](/revenue/revenue-records/) documentation for the full page reference. ## What each amount means Fours maps the raw Azure revenue data into the normalized record as follows: | Revenue record field | Azure source | Meaning | |----------------------|--------------|---------| | **Billed (Invoice amount)** | Estimated revenue | Gross revenue Microsoft billed the customer. | | **Collectable** | Earning amount | What you receive after Microsoft's marketplace fee. | | **Partner fee** | Estimated revenue − earning amount | Microsoft's marketplace fee (typically ~3%). | | **Disburse amount** | Earning amount, once the payout status is *Sent* | Money Microsoft paid out to you. | | **Disburse date** | Payment-sent date | When Microsoft disbursed the funds. | :::info Azure amounts are reported and normalized in **USD**. Microsoft's report does **not** include a separate tax line, so the tax field is not populated for Azure records. ::: :::info Purchases sold through a **reseller (CSP)** are tagged as **Resold** with the reseller's details; direct purchases are tagged **Direct**. Refunds and adjustments are netted into the purchase's totals. ::: ## Sync Revenue sync runs automatically once your Azure Marketplace integration is connected. Fours periodically pulls new revenue and earnings rows and updates the corresponding revenue records. - The **first** sync performs a historical backfill (about one year of data); subsequent syncs are incremental. - A payout appears once Microsoft marks the earning as *Sent* and Fours' next sync ingests it. Until then, the record shows the collectable amount without a disburse date. ### Reissued payouts are reconciled, not stacked When Microsoft reverses a payout, it does not amend the original — it **re-issues the payout under a new earning ID** and drops the retracted one from the revenue report. Left alone, that would leave both the retracted and the replacement earning on the record and double-count the purchase, because the reversing negative line appears only in the earnings report. Fours reconciles instead. After a report streams in completely, for every purchase the report carried a real earning for, Fours **removes the earning rows whose IDs the report no longer lists** — treating a missing earning as a retraction. Purchases the report did not mention are never touched, and a purchase whose replacement rows failed to store is skipped, so nothing is deleted before its replacement exists. :::info The short and long report fetches run independently and can interleave. If a retraction lands between their two report generations, the fetch holding the older snapshot can briefly resurrect a retracted earning or drop its replacement. The next sync covering that month converges the figures again, so any skew lasts at most one fetch cycle. ::: ### Metered lines that cannot be attributed stay unlinked Microsoft's revenue report leaves the asset identifier empty on **metered (usage-based)** lines, so those lines have nothing on them that says which subscription the usage came from. Fours fills the gap only where the report itself proves the answer: another line in the same report naming an asset for the **same purchase** — same customer, product, plan, and private offer — and only when exactly one asset exists for that purchase. When that proof is missing or ambiguous — a customer holding two subscriptions on one plan, for instance — the line is **left unlinked** and falls through to the buyer-and-offer resolver, which declines rather than guesses. An unlinked line is the intended outcome, not a failure. Fours previously keyed these lines on the invoice, on the premise that one invoice covers one asset. That premise is false: an Azure invoice covers every purchase on a billing account, and a billing account spans customers — so the invoice key routinely attached usage to a **different customer's** entitlement, booking money against the wrong buyer with no way to detect it downstream. Revenue that is visibly unattributed is recoverable; revenue attributed to the wrong buyer is not. :::caution Azure revenue data reflects what Microsoft reports in Commercial Marketplace Analytics. If a purchase or payout is missing, confirm it appears in Partner Center first — Fours can only surface what Microsoft has published. ::: ## FAQ ### Why is my collectable amount lower than the billed amount? The collectable amount is your **earning** — the estimated revenue minus Microsoft's marketplace fee. Fours derives the fee as the difference between the two, so it reflects the exact rate Microsoft applied to each purchase (including any incentive or private-offer differences). ### Why don't Azure records show tax? Microsoft's revenue report exposes only gross revenue and net earning; it does not break out a marketplace tax line. Fours therefore leaves the tax field empty for Azure records. ### When will I see a disbursement? A disbursement is recorded once the earning's payout status becomes *Sent*. Earnings that are rejected or not eligible are marked as written off rather than collected. --- Source: https://doc.fours.com/azure-marketplace/ # Azure Marketplace Selling on Azure Marketplace runs through Microsoft Partner Center, so the gating step is on Microsoft's side: your business must be enrolled in the Microsoft AI Cloud Partner Program with a verified Partner ID, and your Partner Center account must be linked to your Azure tenant. Once that is true, Fours connects to Partner Center and manages listings, private offers, entitlements, and metering for you. Microsoft's certification review is the long pole in a net-new listing — budget about three weeks in total — while pointing an offer you already publish in Partner Center at Fours is closer to five days. One piece of vocabulary is worth fixing before you read further. Microsoft calls a listing an **offer**, which is the same thing Fours and the other clouds call a **product** — so one Fours product maps to one Partner Center offer, and every Fours page here means "negotiated deal for one customer" when it says private offer. ## Get listed on Azure Marketplace 1. **[Self-Serve Onboarding Guide](/azure-marketplace/self-serve-onboarding/)** — the phased path from Partner Center account and publisher profile through to your first private offer, at your own pace. 2. **[Integration](/azure-marketplace/integration/)** — the account-eligibility checklist to run in Partner Center first, then how to grant Fours access. 3. **[Pricing Model](/azure-marketplace/pricing-model/)** — Azure offers only Flat Rate and Per User, only Flat Rate supports metered usage, and every plan on the same product must share whichever you pick. 4. **[List Product](/azure-marketplace/list-product/)** — fill in the listing in Fours, submit it, and finish publishing in Partner Center. ## Give one customer their own price - **[Create Private Offer](/azure-marketplace/create-private-offer/)** — a time-bound negotiated deal on an existing plan, priced either as a percentage discount or as an absolute price. - **[Accept Private Offer](/azure-marketplace/accept-private-offer/)** — the buyer's side, including the Enterprise Agreement and Azure subscription roles they need before they can accept. ## Bring a channel partner into the deal - **[CPPO](/azure-marketplace/cppo/)** — extend a margin to a Cloud Solution Provider partner reselling your software, or build a multiparty private offer where several partners contribute to one customer deal. ## Keep the listing and the numbers current - **[Update Product](/azure-marketplace/update-product/)** — what you can change in Fours (the fulfillment URL) versus what has to be changed in Partner Center, broken down by listing status. - **[Revenue](/azure-marketplace/revenue/)** — how Fours joins Partner Center's Commercial Marketplace Analytics revenue report with the earnings export to show billed amounts, marketplace fees, and payout dates. ## Scope and limits :::info Fours creates **SaaS** listings on Azure Marketplace. Private offers can also be sent against an Azure VM product. Your pricing model is fixed once the product is published, and Azure locks a plan's price after publication — to change pricing you add a new plan and stop distributing the old one. Money moves through Partner Center, not Fours: Microsoft invoices your customers, deducts its marketplace fee, and pays you. Billed amounts come from the Commercial Marketplace Analytics revenue report, and Fours records a disbursement only once the earnings export marks that payout **Sent**. ::: --- Source: https://doc.fours.com/gcp-marketplace/self-serve-onboarding/ # Self Serve Onboarding Guide Everything you need to go live on Google Cloud Marketplace with Fours, step by step, at your own pace. --- :::info New to cloud marketplaces? See [What Is a Cloud Marketplace](/concepts/what-is-cloud-marketplace/) for the basics before diving in. ::: ## What to expect This is a self-serve guide — no need to wait for a meeting to get started. GCP has more upfront prerequisites than AWS or Azure, so plan ahead and start early. The full journey from account setup to your first private offer typically takes **4-5 weeks**, most of that being GCP's review period and Solution Architecture Validation rather than your own work time. Your actual hands-on time commitment is roughly **4-6 hours** spread across the process. Use your dedicated Slack channel for questions at any point, or email [support@suger.io](mailto:support@suger.io) for urgent issues — self-serve support is async, with responses within 1 business day. ```d2 direction: down p0: "Phase 0 — Become a GCP vendor\nPartner Hub, MVA, Solution Validation,\nProducer Portal, Fours integration\nDays 1-7, then ~3 week GCP review" p1: "Phase 1 — Account setup\nFours org created\n& approved\nDay 1" p2: "Phase 2 — Create your listing\nBuild & submit for\nGoogle review\nDay 2-3" p3: "Phase 3 — Go live & test\nConfirm listing,\nsend a test private offer\nWeek 4-5" p4: "Phase 4 — CRM integration (optional)\nSalesforce or HubSpot\nanytime after Phase 0" p5: "Phase 5 — Co-Sell setup (optional)\nGCP Co-Sell\nafter the listing is live" p0 -> p1 -> p2 -> p3 p0 -> p4 { style.stroke-dash: 4 } p3 -> p5 { style.stroke-dash: 4 } ``` | Phase | What you're doing | Est. time | | --- | --- | --- | | 0 — Become a GCP vendor | Partner Hub, MVA, Solution Validation, Producer Portal, Fours integration | Days 1-7 (then ~3 week GCP review) | | 1 — Account setup | Create & get approved on the Fours console | Day 1 | | 2 — Create your listing | Build and submit product listing for GCP review | Day 2-3 | | 3 — Go live & test | Confirm listing, send test private offer | Week 4-5 (after GCP review) | | 4 — CRM integration | Connect Salesforce or HubSpot | Anytime after Phase 0 | | 5 — Co-Sell setup | Connect GCP Co-Sell | After listing is live | Work through Phases 0-5 in order — Phases 4 and 5 are optional, skip them if they don't apply to you. :::warning The Solution Architecture Review in Phase 0 is unique to GCP and requires preparation time. Start gathering your architecture diagram and infrastructure estimates early — this is the most common cause of delays. ::: ## Before you start - **Your business** — a registered legal business entity and a company email address (not a personal Gmail or similar). - **A Google Workspace or Cloud Identity account** — required to create a GCP Organization, a prerequisite for becoming a Marketplace vendor. If your company already uses Google Workspace, you're covered. - **A GCP account** — active, with billing enabled. Create one at [cloud.google.com](https://cloud.google.com) if you don't have one. - **Someone with GCP admin access** — a few steps in Phase 0 require managing IAM, service accounts, and Workload Identity Federation in your GCP project (~30-45 minutes). - **Your product** — deployable on GCP (required for Google's Solution Architecture Review), plus a live fulfillment URL and a support email and URL. - **A logo** — a company or product logo in PNG format. Other items like bank account details can be set up as you go. ## Phase 0: Become a GCP Marketplace vendor This phase has more steps than AWS or Azure because Google requires additional validation before vendors can publish products. Work through each step in order — each is a dependency for the next. **Estimated time:** ~4-6 hours of hands-on work, plus 3 to 4 weeks for Google's review and approval process. | Step | Official GCP resource | | --- | --- | | Set up a GCP Organization | [Creating and managing organizations](https://cloud.google.com/resource-manager/docs/creating-managing-organization) | | Create a GCP project | [Create and manage Google Cloud resources](https://cloud.google.com/resource-manager/docs/manage-google-cloud-resources) | | Register on Partner Hub | [Offer software on Google Cloud Marketplace](https://cloud.google.com/marketplace/docs/partners/offer-products) | | Accept the MVA (Marketplace Vendor Agreement) | [Marketplace Vendor Agreement](https://cloud.google.com/terms/marketplace-vendor-agreement) | | Solution Architecture Validation | [Requirements for Google Cloud Marketplace](https://cloud.google.com/marketplace/docs/partners/get-started) | | Submit via Partner Support | [Request assistance with Google Cloud Marketplace](https://cloud.google.com/marketplace/docs/partners/get-support) | | Enable Producer Portal | [Offering SaaS products on Google Cloud Marketplace](https://cloud.google.com/marketplace/docs/partners/integrated-saas) | Once these are complete, connect your GCP Marketplace account to Fours — see [Integrate GCP Marketplace with Fours](/gcp-marketplace/integration/). :::tip **Phase 0 complete when:** your GCP integration shows as connected in the Fours console. ::: ## Phase 1: Account setup Before you can connect marketplaces or create listings, you'll need a Fours organization and access to the Fours Console. **Estimated time:** ~10 minutes of hands-on work, plus up to 1 business day for organization approval. 1. Go to [console.suger.io](https://console.suger.io) and sign up using your company email domain (not a personal email). 2. Your organization stays in a **Pending Approval** state until the Fours team approves it — send a quick message in your shared Slack channel once you've created it so we can process the approval. Once approved, you'll get a confirmation email. Approval typically takes up to 1 business day; if you haven't heard back after that, reach out again in your Slack channel. 3. Once approved, invite the teammates who will participate in the implementation — see [Invite Your Team](/get-started/account/#invite-your-team). :::tip **Phase 1 complete when:** your org is approved and your team is added to the console. ::: ## Phase 2: Create your product listing In this phase, you'll create your Google Cloud Marketplace listing in Fours and submit it to Google for review — this is the listing customers will see when they discover your product in Google Cloud Marketplace. **Estimated time:** ~1-2 hours of hands-on work, plus ~3 weeks for Google's review. In the Fours console, go to **Products → Create Product**, select Google Cloud Marketplace, and complete your listing. Fours uses AI-assisted templates to help generate your initial content — review and customize it before submitting. See [Create and Publish a GCP Marketplace Listing](/gcp-marketplace/list-product/). Unlike AWS and Azure, Google communicates review feedback through your Partner Support ticket rather than email — monitor that ticket throughout the review in case Google requests changes. If you have an active deal waiting on your listing, let your Fours contact know — listings can be expedited in that case. :::tip **Phase 2 complete when:** your listing has been submitted and GCP has confirmed it's under review. ::: ## Phase 3: Go live & test with a private offer Once your listing is approved, confirm it's live and validate the buyer experience end to end before working with real customers. **Estimated time:** Less than 1 hour once your listing has been approved. 1. In the Fours Console, go to **Product**, open your GCP product, and confirm the status is **Public**. Copy the **Marketplace URL** and open it in an incognito window — if it loads, your product is live. 2. Create and accept a private offer using an account you control, to verify your private offer workflow, fulfillment, and entitlement processing all work before inviting real customers. See [Create a GCP Marketplace Private Offer](/gcp-marketplace/create-private-offer/). This is separate from — and happens after — the billing test Fours already ran jointly with Google to validate your listing during Phase 2. Don't skip this step — it's much easier to catch issues here than after a real customer transacts. :::tip **Phase 3 complete when:** your test offer has been sent, accepted, and confirmed in Fours. You're ready for real buyers. ::: ## Phase 4: CRM integration (optional) If your team uses Salesforce or HubSpot, connect it to Fours to manage private offers and co-sell opportunities more efficiently. Skip this phase if you use neither. - Salesforce (~1 hour, requires a Salesforce Admin) — lets your sales team send private offers and share opportunities without leaving Salesforce. See [Integrate Salesforce with Fours](/integrations/salesforce/#overview). - HubSpot (~10 minutes, requires access to install apps and grant CRM permissions in HubSpot) — enables co-sell capabilities from the Fours console. See [Integrate HubSpot with Fours](/integrations/hubspot/). :::tip **Phase 4 complete when:** your CRM is connected to Fours and the integration is ready to use. ::: ## Phase 5: Co-Sell setup (optional) If you plan to co-sell with Google Cloud and your Fours subscription includes Google Cloud co-sell capabilities, complete this phase — otherwise, skip it. Google Cloud co-sell lets you share sales opportunities with your Google account team so they can collaborate with you throughout the sales cycle. **Estimated time:** ~30 minutes for the integration, plus any additional time to complete Google's co-sell requirements. Connect your Google Cloud Partner Network account to Fours — see [GCP Co-Sell](/integrations/gcp-cosell/). Then configure field mapping yourself on the **Co-Sell** page's **Settings** tab, under **Configs**, so opportunities sync correctly between your CRM and Google Cloud — see [Co-Sell Configuration](/cosell/cosell-configuration/). Reach out to your Fours contact only if you need help with complex custom mappings. :::tip **Phase 5 complete when:** your Google Cloud co-sell integration is connected and opportunity syncing has been configured. ::: ## You're live — what's next Congratulations! You're ready to start transacting with customers through GCP Marketplace using Fours. From here, your focus shifts from setup to day-to-day marketplace operations — creating private offers, managing agreements, tracking revenue, and growing your marketplace business. ### Self-serve customers Your onboarding is complete; post in your dedicated Slack channel or email [support@suger.io](mailto:support@suger.io), and expect a response within 1 business day. ### SMB / Mid-Market / Enterprise customers Your Customer Success Manager will schedule a post-launch check-in to help you plan your growth strategy, manage private offers, set up co-sell workflows, and answer product questions. ## Important links :::important Bookmark these — you'll want quick access to them once you're live. ::: | Resource | Where | | --- | --- | | Your GCP listings and private offers | [GCP Producer Portal](https://console.cloud.google.com/producer-portal) | | Create a private offer | [Create a GCP Marketplace Private Offer](/gcp-marketplace/create-private-offer/) | | Check if an invoice has been paid | [Revenue Records](/revenue/revenue-records/) | | Renew or upsell an existing deal | [Private Offers](/console/private-offers/) | | Learn more about the Fours console | [Navigate the Fours Console](/get-started/navigate-console/) | --- Source: https://doc.fours.com/gcp-marketplace/integration/ # Integration Set up Fours to manage your Google Cloud Marketplace and Producer Portal on your behalf — listings, private offers, entitlements, and metering, all from one place. --- ## Overview To sell on Google Cloud Marketplace, your organization must join [Google Cloud Partner Network](https://partners.cloud.google.com) and be approved as a [Google Cloud Marketplace vendor](https://cloud.google.com/marketplace/docs/partners/offer-products#vendor-agreement). See Google's [requirements for your organization](https://cloud.google.com/marketplace/docs/partners/get-started#requirements_for_your_organization) for the full list. Once you're an approved vendor and the integration is in place, Fours can manage product listings, private offers, entitlements, and usage metering on your behalf. Fours authenticates to your GCP project using [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation). The Fours AWS account is configured as an external identity provider in a Workload Identity Pool inside your project, which is authorized to impersonate a service account you create for Fours. No long-lived keys are exchanged. ## Onboarding journey | # | Step | Who does it | | - | --- | --- | | 1 | Become a Google Cloud Marketplace Vendor | You + Google | | 2 | Prepare your GCP project for Fours | You | | 3 | Link the service account inside your Producer Portal | You | | 4 | Set up the reports storage bucket | You | | 5 | Create the integration in the Fours Console | You | After onboarding you can edit, delete, or run multiple integrations. See [Manage your integration](#manage-your-integration) below. ## Step 1: Become a Google Cloud Marketplace vendor Before Fours can manage your marketplace, your business must be an approved Google Cloud Marketplace vendor with access to the Producer Portal. **Prerequisites** - A registered legal business entity - A Google Workspace or **Cloud Identity** account - Your product passes Google's **Solution Architecture Validation** - Agreement to Google's **Marketplace Vendor Agreement (MVA)** 1. **Set up a GCP Organization.** If you don't have one, create it in the [Google Cloud Console](https://console.cloud.google.com/). This requires a Google Workspace or Cloud Identity account. (On a free trial you can create a project without an Organization.) 2. **Register on Partner Hub.** Go to [Partner Hub](https://partners.cloud.google.com), enroll under the **Build** engagement model, then under **View tasks → Partner tasks** click **Initiate onboarding your product to Marketplace**. Confirm your organization meets Google's [vendor requirements](https://cloud.google.com/marketplace/docs/partners/get-started#requirements_for_your_organization) and is a member of Google Cloud Partner Network. 3. **Accept the Marketplace Vendor Agreement (MVA).** Review the [MVA](https://cloud.google.com/terms/marketplace-vendor-agreement?hl=en), then accept it in Partner Hub. You must be a **Partner Admin** to accept it. 4. **Complete Solution Validation.** Google reviews your architecture to confirm your product is deployable on GCP. Submit Google's [Solution Validation Form](https://docs.google.com/forms/d/e/1FAIpQLSesllyRR-HvLFZthYA8Cv4nQRUTOthHGgs-76DY9o2IntUL3A/viewform) with: - **Architecture diagram** — legible, with GCP icons; shows where resources run (GCP, on-prem, or other clouds), customer vs. partner tenancy, and all GCP services used. - **Infrastructure estimate** — from the GCP Pricing Calculator, matching your diagram (Single-Tenant and Multi-Tenant models if applicable). - **Sales projections** — estimated Gross Transaction Value (GTV) for Year 1 and Year 3. :::tip Use the [Architecture Diagram Cheatsheet](https://googlecloudcheatsheet.withgoogle.com/architecture) to build your diagram. ::: 5. **Enable the Producer Portal.** Create a GCP project named `companyname-public`, then submit the [Marketplace Producer Portal Enablement Form](https://docs.google.com/forms/d/e/1FAIpQLSfddn4mwKnqtLNQ-m7IgRZ-bgTz4BOsrEDWCf3XBjc_ogKNnA/viewform). Once approved, you get access to the [Google Cloud Producer Portal](https://console.cloud.google.com/producer-portal) in your project, where you create your listing and manage versions, billing, and pricing. To create the `companyname-public` project you need the `resourcemanager.projects.create` permission (in the **Project Creator** role). In the console, open **Manage Resources**, select your organization, and click **Create Project**. See [Creating and managing projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects). ![GCP Manage Resources page for creating a new project](images/gcp-marketplace-onboarding-playbook-1.png) Enter a project name, choose a billing account, and select a parent organization or folder — or choose "No organization" to create it at the top level — then click **Create**. ![GCP new project details form](images/gcp-marketplace-onboarding-playbook-2.png) :::info Google's marketplace service accounts also need specific roles on your project. The Fours [setup script in Step 2](#step-2-prepare-your-gcp-project-for-fours) grants these for you, so you don't need to configure them by hand. ::: ## Step 2: Prepare your GCP project for Fours You have two options to provision the service account, IAM roles, and Workload Identity Pool that Fours needs: - **Option A — Run the setup script** (recommended). One script in Cloud Shell does everything. - **Option B — Set up manually** through the GCP console. Pick one. Both produce the same result. ### Option A: Run the setup script (recommended) Open [Cloud Shell](https://console.cloud.google.com/?cloudshell=true) in the GCP project you want to integrate, then paste and run the script below. ```bash #!/bin/bash # Set up the GCP resources required for the Suger integration. # Safe to re-run: idempotent guards skip resources that already exist. set -euo pipefail SERVICE_ACCOUNT_NAME="suger-integration" PROJECT_ID=$(gcloud config get-value project 2>/dev/null || true) if [[ -z "$PROJECT_ID" ]]; then echo "ERROR: No active GCP project. Run: gcloud config set project YOUR_PROJECT_ID" >&2 exit 1 fi PROJECT_NUMBER=$(gcloud projects describe "$PROJECT_ID" --format="value(projectNumber)") SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" # 1. Enable required APIs (idempotent). gcloud services enable \ iam.googleapis.com \ cloudresourcemanager.googleapis.com \ iamcredentials.googleapis.com \ sts.googleapis.com \ servicecontrol.googleapis.com \ cloudcommerceconsumerprocurement.googleapis.com \ servicemanagement.googleapis.com \ serviceusage.googleapis.com # 2. Create the Suger service account (skip if it already exists). gcloud iam service-accounts describe "$SERVICE_ACCOUNT_EMAIL" >/dev/null 2>&1 \ || gcloud iam service-accounts create "$SERVICE_ACCOUNT_NAME" \ --display-name="Suger Integration Service Account" # 3. Grant the service account the IAM roles it needs (idempotent). for ROLE in \ roles/editor \ roles/servicemanagement.admin \ roles/servicemanagement.serviceController \ roles/commerceproducer.admin \ roles/consumerprocurement.entitlementManager \ roles/consumerprocurement.orderAdmin \ roles/commercepricemanagement.privateOffersAdmin \ roles/pubsub.editor \ roles/iam.serviceAccountTokenCreator do gcloud projects add-iam-policy-binding "$PROJECT_ID" \ --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \ --role="$ROLE" \ --condition=None >/dev/null done # 4. Create the Workload Identity Pool and add the Suger AWS account as a provider # (skip each if it already exists). gcloud iam workload-identity-pools describe suger-wip \ --location=global >/dev/null 2>&1 \ || gcloud iam workload-identity-pools create suger-wip \ --location=global \ --description="Suger Workload Identity Pool" gcloud iam workload-identity-pools providers describe suger \ --location=global \ --workload-identity-pool=suger-wip >/dev/null 2>&1 \ || gcloud iam workload-identity-pools providers create-aws suger \ --location=global \ --workload-identity-pool=suger-wip \ --account-id=SUGER_AWS_ACCOUNT_ID # 5. Allow the Suger backend services to impersonate the service account (idempotent). # Each binding names a specific AWS assumed-role that a Suger service pod runs as, # so no other identity in Suger's AWS account can complete the token exchange. for SUGER_ROLE in partner-service marketplace-service workflow-service do gcloud iam service-accounts add-iam-policy-binding "$SERVICE_ACCOUNT_EMAIL" \ --member="principalSet://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/suger-wip/attribute.aws_role/arn:aws:sts::SUGER_AWS_ACCOUNT_ID:assumed-role/$SUGER_ROLE" \ --role="roles/iam.workloadIdentityUser" >/dev/null done # 6. Grant the Suger support user the roles needed to assist with marketplace operations # (idempotent). for ROLE in \ roles/viewer \ roles/commerceproducer.admin \ roles/commercepricemanagement.privateOffersAdmin \ roles/servicemanagement.admin do gcloud projects add-iam-policy-binding "$PROJECT_ID" \ --member="user:gcpdev@suger.io" \ --role="$ROLE" \ --condition=None >/dev/null done # 7. Grant Google's marketplace service accounts the roles required by GCP Marketplace # (idempotent). for BINDING in \ "group:cloud-commerce-marketplace-onboarding@twosync-src.google.com|roles/editor" \ "group:cloud-commerce-marketplace-onboarding@twosync-src.google.com|roles/servicemanagement.admin" \ "serviceAccount:cloud-commerce-producer@system.gserviceaccount.com|roles/servicemanagement.configEditor" \ "serviceAccount:cloud-commerce-saastester@system.gserviceaccount.com|roles/commerceproducer.viewer" \ "serviceAccount:cloud-commerce-procurement@system.gserviceaccount.com|roles/serviceusage.serviceUsageAdmin" \ "serviceAccount:cloud-commerce-procurement@system.gserviceaccount.com|roles/servicemanagement.serviceController" \ "serviceAccount:cloud-commerce-procurement@system.gserviceaccount.com|roles/servicemanagement.admin" do MEMBER="${BINDING%|*}" ROLE="${BINDING#*|}" gcloud projects add-iam-policy-binding "$PROJECT_ID" \ --member="$MEMBER" \ --role="$ROLE" \ --condition=None >/dev/null done # Print the values you'll need when you create the integration in Suger Console. echo "PROJECT_ID: $PROJECT_ID" echo "PROJECT_NUMBER: $PROJECT_NUMBER" echo "Workload Identity Pool: suger-wip" echo "AWS Provider ID: suger" echo "Service Account Email: $SERVICE_ACCOUNT_EMAIL" ``` :::tip `SUGER_AWS_ACCOUNT_ID` is the external identity Fours uses to impersonate your service account. Contact [support@suger.io](mailto:support@suger.io) for the Fours AWS Account ID, then substitute it in the script before you run it. ::: **Save the five values printed at the end** — you'll paste them into the Fours Console in Step 5. #### Also required: Billing Account Viewer at the organization level So Fours can auto-validate billing account IDs when creating private offers and resale (CPPO) offers, also grant the service account `Billing Account Viewer` at the **GCP organization** level (the script only operates at the project level): ```bash gcloud organizations add-iam-policy-binding ORG_ID \ --member="serviceAccount:suger-integration@PROJECT_ID.iam.gserviceaccount.com" \ --role="roles/billing.viewer" ``` This requires a user with `Organization Administrator` access. Find your `ORG_ID` with `gcloud organizations list`. ### Option B: Set up manually If you prefer to click through the console, here are the same steps in detail. 1. **Create a service account.** Follow Google's [guide](https://cloud.google.com/iam/docs/service-accounts-create) and name it `suger-integration`. Grant it these roles in the **GCP project**: - Project Editor (or Viewer) - Commerce Producer Admin - Commerce Price Management Private Offers Admin - Consumer Procurement Entitlement Manager - Consumer Procurement Order Administrator - Pub/Sub Editor - Service Account Token Creator - Service Controller - Service Management Administrator And at the **GCP organization** level: - Billing Account Viewer 2. **Enable the required APIs.** Use this [quick link](https://console.cloud.google.com/apis/enableflow?apiid=iam.googleapis.com,cloudresourcemanager.googleapis.com,iamcredentials.googleapis.com,sts.googleapis.com,servicecontrol.googleapis.com,cloudcommerceconsumerprocurement.googleapis.com,servicemanagement.googleapis.com,serviceusage.googleapis.com) to enable all eight at once: - Identity and Access Management (IAM) API - Cloud Resource Manager API - IAM Service Account Credentials API - Security Token Service API - Service Control API - Cloud Commerce Consumer Procurement API - Service Management API - Service Usage API 3. **Create a Workload Identity Pool** named `suger-wip`. See Google's [guide](https://cloud.google.com/iam/docs/workload-identity-federation). 4. **Add the Fours AWS account as an Identity Provider** in the pool. Contact [support@suger.io](mailto:support@suger.io) for the Fours AWS Account ID. Name the provider `suger`. > Add Identity Provider screenshot 5. **Authorize the pool to impersonate the service account.** Open the Workload Identity Pool, click **GRANT ACCESS**, select the `suger-integration` service account, and save. > Grant access to service account screenshot When the dialog appears, select the `suger` Identity Provider. > Select identity provider dialog 6. **Grant Google's marketplace service accounts** the roles below on your **GCP project**: - `cloud-commerce-marketplace-onboarding@twosync-src.google.com` — Project Editor + Service Management Administrator - `cloud-commerce-producer@system.gserviceaccount.com` — Service Config Editor - `cloud-commerce-saastester@system.gserviceaccount.com` — Commerce Producer Viewer - `cloud-commerce-procurement@system.gserviceaccount.com` — Service Controller + Service Usage Admin + Service Management Administrator `cloud-commerce-procurement@system.gserviceaccount.com` also needs **Service Consumer** at the **service** level for each of your product services. Run this once per product service after publishing: ```bash gcloud endpoints services add-iam-policy-binding \ "{your-product-service-id}.endpoints.{your-gcp-project-id}.cloud.goog" \ --member='serviceAccount:cloud-commerce-procurement@system.gserviceaccount.com' \ --role='roles/servicemanagement.serviceConsumer' ``` 7. **Grant the Fours support user (`gcpdev@suger.io`)** the roles below on your **GCP project**. These let Fours support inspect Producer Portal, reports, and settings when helping you troubleshoot — Option A's setup script grants them automatically, so Option B must do the same: - Viewer - Commerce Producer Admin - Commerce Price Management Private Offers Admin - Service Management Administrator Or run these commands: ```bash for ROLE in \ roles/viewer \ roles/commerceproducer.admin \ roles/commercepricemanagement.privateOffersAdmin \ roles/servicemanagement.admin do gcloud projects add-iam-policy-binding "$PROJECT_ID" \ --member="user:gcpdev@suger.io" \ --role="$ROLE" done ``` ## Step 3: Link the service account in Producer Portal The IAM roles from Step 2 cover Google Cloud, but Producer Portal also needs the service account linked inside its own UI. Open [Producer Portal](https://console.cloud.google.com/producer-portal) and follow Google's [backend integration guide](https://cloud.google.com/marketplace/docs/partners/integrated-saas/backend-integration) to authorize `suger-integration@{PROJECT_ID}.iam.gserviceaccount.com` for: - Partner Procurement API integration - Cloud Pub/Sub integration - Service Control API integration (only required if your product reports usage) ## Step 4: Set up the reports storage bucket Fours reads your GCP Marketplace revenue and usage reports from a Cloud Storage bucket. Follow Google's [reports setup guide](https://cloud.google.com/marketplace/docs/partners/reports/set-up-reports) to create and configure the bucket. Keep the bucket name handy — you'll enter it in the next step. :::info When configuring the destination, under Reports to export, make sure to select the **Detailed disbursements** checkbox specifically. This is a separate report type from the basic Disbursements report and isn't selected by default, skipping it means revenue and disbursement data won't have the detailed breakdown Fours needs to reconcile properly. ![GCP detailed disbursements checked](images/gcp-detailed-disbursment-checked.png) ::: ## Step 5: Create the integration in Fours Console Open the [integrations page](https://console.suger.io/settings?tab=integrations) in Fours Console, click **CONNECT** next to Google Cloud, and fill in the form using the values from the earlier steps: | Field | Value | | --- | --- | | **GCP Project ID** | `PROJECT_ID` from the script output | | **GCP Project Number** | `PROJECT_NUMBER` from the script output | | **Workload Identity Pool ID** | `suger-wip` | | **Identity Provider ID** | `suger` | | **Service Account Email** | `suger-integration@{PROJECT_ID}.iam.gserviceaccount.com` | | **Marketplace Partner/Provider ID** | The Partner/Provider ID assigned when your business is approved for Producer Portal. Often the same as your Project ID. | | **Report Bucket Name** | The Cloud Storage bucket from Step 4 | Save the integration. Fours immediately starts syncing products and offers from your Producer Portal. Once the integration verifies successfully, Fours also starts a [full sync](#run-a-full-sync) that imports its history. ## Listing stages and approval timelines Once you're integrated, Fours handles most of the technical and administrative work of listing your SaaS product on GCP Marketplace. Listing moves through four stages, each with its own Google approval time. > **Estimated total time to go live:** ~3–4 weeks ### 1. Product listing details Submit your product name, logo, description, support and sales contacts, URLs, and keywords in the [GCP Producer Portal](https://console.cloud.google.com/producer-portal). **Approval time:** 3–4 business days ### 2. Pricing model Choose your pricing model (flat-rate, usage-based, and so on) and define metrics. To offer a free trial, follow Google's [trial software guidance](https://docs.cloud.google.com/marketplace/docs/partners/integrated-saas/select-pricing#offering-trial-software), which links to the current intake form. **Approval time:** 3–4 business days ### 3. Technical integration Link service accounts and enable the Partner Procurement API, Cloud Pub/Sub, and (optionally) the Service Control API; set up SSO or login URLs using Fours' endpoints; and grant the required IAM roles. Steps 2–3 above cover the Fours side of this work. **Approval time:** ~1 week ### 4. Billing integration Google reviews your service account setup, entitlement flow, and metering requirements. **Approval time:** 1–2 weeks When all four stages are approved, Fours syncs the listing and its status becomes **Public**. :::info **Consumption tracking (optional).** If your solution includes a data plane in the customer's project, apply for a **Consumption Label** through Google's [Partner Consumption Tracking](https://docs.cloud.google.com/marketplace/docs/partners/integrated-saas/partner-consumption-tracking) guide, which links to the current Partner Consumption Tracking Initiative form, and implement tracking via Terraform, CLI, or API. ::: | Stage | Estimated approval time | | --- | --- | | Listing details | 3–4 business days | | Pricing review | 3–4 business days | | Technical integration | ~1 week | | Billing integration | 1–2 weeks | --- ## Manage your integration ### Edit integration You can update an existing integration at any time: - **Enable Entitlement End Soon Notification** — when on, choose a window of 10–60 days. Fours will send an initial notification when an entitlement is approaching its end, followed by reminders every 5 days. Configure recipients via the [email notification guide](/settings/email-notification/#configuration) using the scope `END_SOON.ENTITLEMENT`. - **Enable Marketplace** — when on, Fours syncs products and private offers from Producer Portal. - **Enable PrivateOffer API** — when on, Fours syncs your catalog and your plain private offers through Google's Commerce Producer API instead of the browser-driven path. - **Enable Resale** — when on, Fours syncs reseller private offer plans for this project's organization. - **Last Full Sync** — read-only: the outcome of the integration's most recent full sync. See [Run a full sync](#run-a-full-sync). :::info Make sure the Fours service account has the right permissions before enabling these flags. ::: #### About Enable PrivateOffer API The API path is the more direct integration with Google, but it does not yet cover every offer type. With the toggle on: | Offer type | Path used | | ---------- | --------- | | Products and plain private offers | Commerce Producer API | | Replacement (amendment) offers | Commerce Producer API | | Reseller authorizations (`CPPO_OUT`) | Browser-driven path (unchanged) | Reseller authorizations are the one exclusion — Google's SDK does not support them yet, so they keep working exactly as before and you don't need to change how you create them. Two things change once replacement offers run through the API. Google checks *before* creating anything whether the replacement is allowed and which offer it must replace, so a replacement that would have failed later is now refused up front with a specific explanation and nothing is created — see [Why a replacement offer was refused](/gcp-marketplace/create-private-offer/#why-a-replacement-offer-was-refused). And a coterm-aligned replacement on a standard billing interval must carry a duration rather than an end date — see [Coterm and standard billing intervals](/gcp-marketplace/create-private-offer/#coterm-and-standard-billing-intervals). Cancelling an offer (**Cancel**) and extending its expiry date (**More actions → Extend Expiry Date**) follow the toggle's **current** setting, whatever created the offer. With the toggle on, Fours cancels and extends an offer through the API once it has recorded the offer's Google ID — including an offer created on the browser-driven path, and one someone built in Producer Portal that Fours picked up by syncing. An offer without a recorded Google ID goes to the browser-driven path, and so does every reseller authorization. ```d2 direction: right action: "Cancel or extend\nan offer" resale: "Reseller\nauthorization?" { shape: diamond } toggle: "Enable PrivateOffer API\non right now?" { shape: diamond } named: "Google ID recorded\nfor the offer?" { shape: diamond } api: "Commerce Producer API" browser: "Browser-driven path" action -> resale resale -> browser: "yes" resale -> toggle: "no" toggle -> browser: "off" toggle -> named: "on" named -> api: "yes" named -> browser: "no" ``` :::info Turning the toggle off With the toggle off, the browser-driven path also handles offers that were created through the API or picked up by its sync: Fours addresses each one the way Producer Portal does. On those offers, **Cancel**, **More actions → Extend Expiry Date**, **More actions → Create Amendment** (shown for an accepted offer that carries the buyer's billing account and its Google ID), and cloning with **Cancel the existing offer at the publishing of this offer** keep working. The exception is an offer Fours cannot address that way — see [Troubleshooting](#troubleshooting). ::: When the offer detail page shows a **GCP Data Source** row, it records the path Fours used to create the offer — use it to check whether a particular offer went through the API or the older path. An offer Fours picked up by syncing, rather than created, may not show the row. Either way, the row does not decide how the offer is cancelled or extended. ![Enable Marketplace and Resale](./images/gcp_enable_marketplace_resale.jpg) With the toggle on, Fours imports your private offers from Google through the API. The hourly sync reads only offers that changed in the last 7 days. To import older offers — or ones Fours skipped, such as offers for a product you onboarded after they were last changed — run a [full sync](#run-a-full-sync), which reads every offer whatever its age. The same sync brings in the documents of an offer someone built in Producer Portal. When it reads an offer that has no EULA recorded in Fours yet, Fours records the offer's EULA — Google's standard EULA, or the PDF of your custom one — and, for a professional-services offer, its statement of work. The offer's **EULA** download then works on the offer and entitlement pages, and a clone starts from those documents — see [Start from an existing offer](/gcp-marketplace/create-private-offer/#step-1-open-the-private-offer-flow). Fours records them once: if you later replace a document in Producer Portal, Fours keeps the one it recorded. An offer last changed more than 7 days ago gets its documents on the next full sync. ### Run a full sync A full sync re-imports a GCP Marketplace integration's history in one background run, within what the integration's settings allow: with **Enable PrivateOffer API** on it reads every private offer, of any age, and while **Create Entitlement From Offers (MaaS)** is off it reads every buyer account and entitlement — along with your products, your marketplace reports and the revenue records built from them. Anything a setting rules out stays with the browser-driven sync, and its step shows as **Skipped** (see the table below). Use a full sync after you onboard a product whose offers were made earlier, or to check that everything has been imported. To start one, open the [integrations page](https://console.suger.io/settings?tab=integrations), open the **⋯** menu on the GCP Marketplace card, and choose **Full sync** — the item right after **Sync**. In the **Start a full sync?** dialog, choose **Start full sync**. The console confirms with *GCP full sync started*, and the run continues in the background; for a large catalog it can take several hours. - **Full sync** is available once the integration is verified, and is greyed out while a run is in progress. Only one full sync of an integration runs at a time. - Fours also starts a full sync on its own each time the integration verifies successfully. - Offers that Google last changed more than 7 days before the run started are imported without sending offer notifications or Salesforce updates for them. ```d2 direction: right start: "Full sync starts\n(menu, or a successful verify)" products: "Products" offers: "Private offers\nevery offer, any age" entitlements: "Buyer accounts\nand entitlements" reports: "Reports\nfrom Report Start Date\nor one year back" revenue: "Revenue records\nup to two days\nbefore the start" panel: "Last Full Sync\nshows each step" start -> products -> offers -> entitlements -> revenue -> panel start -> reports: "in parallel" reports -> revenue ``` Each step reads one part of your history, and shows as **Skipped** when a setting hands that part to another path: | Step | What it reads | Skipped when | | --- | --- | --- | | **Products** | Your products | **Enable Marketplace** is on and **Enable PrivateOffer API** is off — the browser-driven sync handles products | | **Private offers** | Every private offer, with no date filter | **Enable PrivateOffer API** is off | | **Buyer accounts**, **Entitlements** | Every buyer account and entitlement | **Create Entitlement From Offers (MaaS)** is on | | **Reports** | The Insights, Charges and Usage, Disbursements and Detailed Disbursements reports, from **Report Start Date** — or one year back when none is set — up to the start of the run; Fours then refreshes entitlement and buyer details from them | The integration has no **GCP Project Number** | | **Revenue records** | Rebuilt from those reports, up to two days before the run started | The integration has no **GCP Project Number**, or **Revenue Record Sync Disabled** is on | The outcome shows in the integration's edit dialog, under **Last Full Sync**: - An overall status — **Running**, **Succeeded**, **Partially succeeded** or **Failed** — with the start and finish times. A step that fails doesn't stop the run; the next one still runs. - How many private offers were read, synced, skipped and failed, and how many entitlements were read, synced and failed. - Each step's status and message, and the first errors. A run still shown as running more than 12½ hours after it started reads **Stopped**, with *The run stopped past its time limit without recording a result. Start it again.* Before any run, the panel reads *No full sync has run yet.* ### Delete integration You can delete a GCP integration like any other. **Deletion is immediate and permanent** — there is no recovery window. Re-creating the integration later starts fresh. ### Run multiple integrations You can connect multiple GCP Marketplace integrations under a single Fours organization. Each one operates independently. 1. Create a new Fours organization in the Fours Console and wait for it to be approved. 2. Set up the second GCP Marketplace integration inside the new organization. 3. Email [support@suger.io](mailto:support@suger.io) with **both** the new and the old Fours organization IDs. Support will merge them — keeping the original organization and removing the new one — while preserving both GCP integrations under the original. :::tip - Once set up, both integrations appear on the Fours Console integration page and can be edited or deleted independently. - Private offer creation, usage reporting, and revenue reports work identically across the Fours web console, Salesforce app, and HubSpot app. Fours routes each request to the right integration automatically. ::: ## Grant additional access to the Fours support team The GCP Marketplace API doesn't yet cover every operation. To let the Fours support team help with operations the API can't perform, grant the **Fours support user account** these IAM roles on your **GCP project** (the setup script already grants the first four): - Viewer - Commerce Producer Admin - Commerce Price Management Private Offers Admin - Service Management Administrator - Consumer Procurement Entitlement Manager - Consumer Procurement Order Administrator If you also want Fours to support resale offer discounts (CPPO), grant the support user these roles at the **GCP organization** level: - Commerce Business Enablement Configuration Admin - Commerce Business Enablement Reseller Discount Admin - Commerce Producer Admin :::tip Email [support@suger.io](mailto:support@suger.io) to get the Fours support user account email address. ::: ## Troubleshooting **`gcloud auth activate-service-account` fails with "domain not allowed".** Your GCP organization restricts which identities can be added via the `iam.allowedPolicyMemberDomains` org policy. Ask your Org Admin to allow the `suger.io` domain, or run the setup from a project that isn't subject to that policy. **`Permission 'iam.serviceAccounts.getAccessToken' denied on resource`.** The Workload Identity Pool hasn't been granted permission to impersonate the service account. Re-run step 5 of the setup script (or the equivalent manual step) to bind `roles/iam.workloadIdentityUser` to the principal set for the pool. **`Error 403: The caller does not have permission, forbidden`.** The Marketplace Partner/Provider ID configured on the Fours integration doesn't match the one assigned in Producer Portal. Open the integration's edit dialog and correct the Partner ID. **Private offers are missing after you onboard a product (Enable PrivateOffer API on).** Fours skips an offer whose product is not in Fours yet, and the hourly sync reads only offers changed in the last 7 days — so offers for a product you onboarded later may not come in on their own. Run a [full sync](#run-a-full-sync): it reads every offer whatever its age, and its **Last Full Sync** panel counts the offers it skipped. See [About Enable PrivateOffer API](#about-enable-privateoffer-api). **Cancelling an offer fails with "Failed to cancel offer: the product has no GCP service name…" (Enable PrivateOffer API off).** With the toggle off, Fours addresses an offer that was created or synced through the API from its product's GCP service name and the integration's GCP Project Number. When the product has no service name in Fours, or the integration has no **GCP Project Number** (the message then names the missing project number instead), the browser-driven path cannot reach the offer, so cancelling, extending or amending it fails. Edit the integration, turn **Enable PrivateOffer API** back on, and try again. See [About Enable PrivateOffer API](/gcp-marketplace/integration/#about-enable-privateoffer-api). **Fours fails to sync entitlements from GCP Marketplace.** The Fours service account is missing from one of the technical integration sections of your product listing. Open Producer Portal → your product → Technical Integration and confirm `suger-integration@{PROJECT_ID}.iam.gserviceaccount.com` is linked under Partner Procurement API, Cloud Pub/Sub, and (for usage-based products) Service Control API. ## Key resources - [Get started on GCP Marketplace](https://cloud.google.com/marketplace/docs/partners/get-started) - [Initiate product onboarding](https://cloud.google.com/marketplace/docs/partners/offer-products#initiate-onboarding) - [Partner Hub portal](https://partners.cloud.google.com/?hl=en) - [Report types](https://docs.cloud.google.com/marketplace/docs/partners/reports/report-types) --- Source: https://doc.fours.com/gcp-marketplace/pricing-model/ # Pricing Model GCP Marketplace Product Pricing Models --- ## Overview There are four pricing models for the SaaS product in GCP marketplace: **Free**, **Subscription based**, **Usage based** and **Combined**. You can choose one or multiple of them in your product listing. ## Free Customers only pay for the Google Cloud resources that they use. If you are offering your product free of charge, skip to [Submitting your pricing for review](https://cloud.google.com/marketplace/docs/partners/integrated-saas/select-pricing). ## Subscription based It is also called as commit-only pricing model. Customers pay a flat monthly or yearly fee for using your software, no matter how much usage they actually use finally. For partial months, the cost is prorated. Customers can change their subscription plan to increase their service level or subscription period, such as: - Switch from a shorter subscription period to a longer period, within the same service level. For example, customers can switch from a Standard monthly plan to a Standard 1-year plan. - Upgrade from a lower to a higher service level, with the same or a longer subscription period. For example, customers can upgrade from a Standard 1-year plan to a Pro 1-year plan. - A combination of the changes above. ## Usage based It is also called as pay-as-you-go pricing model. Customers pay for your software based on measurements that you choose, called metrics, such as data or storage. For example, you can set your price by gibibyte-hours of storage. If you choose a usage-based pricing model, your app must measure and report usage information to Google. The following table includes examples of some metrics: | Metric Name | Metric Unit | Metric Price per Unit | | ----------- | ----------- | ------------ | | compute service | 2 CUP, 8GB RAM per hour as one unit | $0.1 | | storage service | 1GB per hour as one unit | $0.04 | | network volume | 1GB as one unit | $0.2 | ## Combined In a combined pricing model, customers pay a base subscription fee for using your software, and additional charges based on their usage. You can include a specific quantity of usage in your base fee. For example, the following pricing model has base subscription plans that include a number of API requests, and additional charges as customers increase their usage: | Standard Plan | Pro Plan | Enterprise Plan | | ----------- | ----------- | ------------ | |
  • $10 / month subscription fee
  • $0 per request for 1000 API requests
  • $0.002 per request for 1000+ API requests
|
  • $40 / month subscription fee
  • $0 per request for 2000 API requests
  • $0.005 per request for 2000+ API requests
|
  • $100 / month subscription fee
  • $0 per request for 10000 API requests
  • $0.008 per request for 10000+ API requests
| :::danger - For any pricing model of `Subscription-based`, `Usage-based` and `Combined`, you can also offer a [free trial](https://docs.cloud.google.com/marketplace/docs/partners/integrated-saas/select-pricing#offering-trial-software) of your product by filling out the [Cloud Marketplace solution trial intake form](https://docs.google.com/forms/d/e/1FAIpQLScECsEH8dnkkh0m-d_WlQr7wVz0m16XKOgHD7HMO37CifErXw/viewform). ::: --- Source: https://doc.fours.com/gcp-marketplace/list-product/ # List & Update Product List your SaaS products in GCP Marketplace and keep them up to date, fully managed by Fours on your behalf. --- ## Overview List your products/services via the [GCP Producer Portal](https://console.cloud.google.com/producer-portal/overview) so your buyers can search and purchase your listings in [GCP Marketplace](https://console.cloud.google.com/marketplace). More details can be found in the [official guidance](https://docs.cloud.google.com/marketplace/docs/partners/integrated-saas/set-up-environment). Keep the following in mind as you work through the process: - GCP uses a **phased approval process**. Each phase must be approved before you can move to the next. - Changes made after submission restart the review for that phase and may delay your go-live timeline. - Some steps are completed in the Fours Console, while others must be completed directly in the GCP Producer Portal because of GCP API limitations. The more complete your information is upfront, the smoother the approval process will be. :::info **Product vs. Listing** — In Fours, a **product** is your centralized listing configuration and system of record. In Google Cloud Marketplace, buyers see and purchase a **listing**. Each product in Fours maps to one Google Cloud Marketplace listing. ::: ## Prerequisites Make sure the following are already in place before creating your listing in Fours. ### Google Cloud Marketplace - **Confirm your Producer Portal access** — open the [Marketplace Producer Portal](https://console.cloud.google.com/producer-portal) and check that you can log in. If you don't have access, you may need to complete the Solution Architecture Review first. This requires submitting the following through a [Partner Support ticket](https://cloud.google.com/marketplace/docs/partners/get-support): - An architecture diagram - A cost estimate from the [GCP Pricing Calculator](https://cloud.google.com/products/calculator) - Year 1 and Year 3 sales projections - **Set up your payment profile and tax information** — open the **Payments** tab inside the Producer Portal and complete your payment profile and tax forms (W-8 or W-9 depending on your location). See the [step-by-step guide](https://cloud.google.com/marketplace/docs/partners/receive-payments). - **Pricing details** — finalize your [pricing model](/gcp-marketplace/pricing-model), plan names, whether your pricing will be public or private, and any usage-based dimensions before you begin. - **At least one product feature** — prepare a name and short description for each feature you want shown on your listing page. GCP requires at least one. - **EULA** — decide whether you'll use the [Google Cloud Marketplace Standard EULA](https://cloud.google.com/terms/marketplace/eula-standard-v2-01272021) or your own. If using a custom one, have the public URL ready. GCP only accepts URLs, not uploaded documents. ### Fours You need **Admin** access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). ## Create Your Product Draft in Fours Before filling out the GCP Producer Portal, create a product draft in the Fours Console first. This draft acts as: - A reference you can copy from while creating your GCP listing. - The product record Fours will later link to your GCP Marketplace listing for private offers, entitlement tracking, and revenue reconciliation. Because of GCP API limitations, listings must still be created manually in the GCP Producer Portal. ### Step 1 — Start a new product draft 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product), then click **+ New Product**. ![+ New Product button in the Fours Console](images/create-and-publish-a-google-cloud-market-1.png) 2. Select **GCP Marketplace** as the **Marketplace**. ![Choose GCP Marketplace in the Fours Console](images/create-and-publish-a-google-cloud-market-2.webp) 3. *(Optional)* Use **AI Autofill** to help generate initial descriptions, categories, and keywords. Click **AI Auto Fill**, insert your website, and click **Submit**. ![AI Auto Fill dialog in the Fours Console](images/create-a-product-listing-saas-3.png) :::tip AI Autofill is a starting point only. It pulls data from your website and may make assumptions, so always review and adjust the results before saving. ::: ### Step 2 — Fill in the core product details Complete the product detail fields: - **Product Name** — a unique, identifiable name. Required. - **Tagline** — a short, catchy snippet shown when buyers browse in Marketplace. - **Product Image** — upload your PNG image for the listing. Requirements: - Transparent background; horizontal or square layout. - Minimum width and height: 130 × 130px. - Maximum width and height: 512 × 512px. - Maximum file size: 256kB. - **Product Overview** — a brief summary highlighting your product's features and capabilities. - **Product Info Link** — a URL where users can get more details. - **Product Category** — select up to 4 categories that describe your product. - **Documentation** — links to guides, videos, FAQs, or other resources. - **Support Description** — a brief description of the support you offer. - **Support URL** — a link to your support or contact page. - **License** — add license agreements; include multiple if needed. - **URL segment** - **Search Metadata** — a short description for SEO. - **Search Keywords** — keywords for Marketplace search. Press **Enter** after each one. ### Step 3 — Review and save 1. Review all entered details for accuracy and completeness. 2. Choose how to finalize: - **Save as draft** — use this while you're still filling things out or if your GCP Marketplace integration isn't yet complete. - **Preview** — always check this before publishing to catch issues. - **Create** — this finalizes your product. ![Product listing form in the Fours Console](images/create-a-product-listing-saas-4.png) ## Complete the GCP Approval Phases Because of GCP API constraints, you must complete your pricing and technical configurations directly in the GCP Producer Portal instead of Fours. GCP reviews your listing in sequential phases; each one must be approved before the next can begin. ### Step 1 — Define product information 1. Go to the GCP Producer Portal and define your [pricing model](/gcp-marketplace/pricing-model) (Free, Subscription-based, Usage-based, or Combined). 2. Set the public price for each plan and define your features. ### Step 2 — Complete technical integration The technical integration includes two parts: **Billing Integration** and **Frontend Integration**. 1. **Billing Integration** — on the Overview page of your product in the GCP Producer Portal, go to the `Technical integration` section and click `BILLING INTEGRATION`. Link two service accounts with three integrations, as listed below, to enable the **Partner Procurement API**, **Cloud Pub/Sub**, and **Service Control API**. | Service Accounts | Integrations | | ---------------- | ------------ | |
  • cloud-commerce-procurement@system.gserviceaccount.com
  • The service account created in step 4 of [GCP Integration](/gcp-marketplace/integration)
|
  • Partner Procurement API integration
  • Cloud Pub/Sub integration
  • Service control API integration (only for products with usage fees)
| 2. **Frontend Integration** — on the Overview page of your product in the GCP Producer Portal, go to the `Technical integration` section and click `FRONTEND INTEGRATION`. Route your **Sign-up URL** and **SSO Login URL** through Fours' endpoints so Fours can correctly capture entitlement IDs during buyer checkout. Enter the fields as shown in the image below, using the values in the table. > Frontend Integration sign-up and SSO login URL fields in GCP Producer Portal | Input Field | Value | | ----------- | ----- | | Sign up URL | `https://api.suger.cloud/public/signup/gcp/orgId/{your-suger-org-id}/{your-gcp-product-id}` | | If Enable SSO login | **SSO URL**: `https://api.suger.cloud/public/login/gcp/orgId/{your-suger-org-id}/{your-gcp-product-id}` | | If Disable SSO login | **Login URL**: `https://api.suger.cloud/public/login/gcp/orgId/{your-suger-org-id}/{your-gcp-product-id}` | :::tip - No matter whether `SSO login` is enabled or disabled, the login URL is the same: `https://api.suger.cloud/public/login/gcp/orgId/{your-suger-org-id}/{your-gcp-product-id}`. - If `SSO login` is enabled, the redirected `login URL` contains three query parameters: `partner`, `sugerEntitlementId`, and `x-gcp-marketplace-token`. Here is the [official guidance](https://docs.cloud.google.com/marketplace/docs/partners/integrated-saas/frontend-integration#verify-jwt) to verify the `x-gcp-marketplace-token` JWT token. - If `SSO login` is not enabled, the redirected login URL doesn't contain any query parameters. ::: 3. Run the commands below in the GCP console terminal to grant the `serviceConsumer` and `serviceController` roles to `cloud-commerce-procurement@system.gserviceaccount.com` for your product listing. ```shell gcloud endpoints services add-iam-policy-binding \ {your-gcp-product-id}.endpoints.{your-gcp-marketplace-project-id}.cloud.goog \ --member='serviceAccount:cloud-commerce-procurement@system.gserviceaccount.com' \ --role='roles/servicemanagement.serviceConsumer' ``` ```shell gcloud endpoints services add-iam-policy-binding \ {your-gcp-product-id}.endpoints.{your-gcp-marketplace-project-id}.cloud.goog \ --member='serviceAccount:cloud-commerce-procurement@system.gserviceaccount.com' \ --role='roles/servicemanagement.serviceController' ``` To make the product listing publicly live: ```shell gcloud endpoints services add-iam-policy-binding \ {your-gcp-product-id}.endpoints.{your-gcp-marketplace-project-id}.cloud.goog \ --member='allUsers' \ --role='roles/servicemanagement.serviceConsumer' ``` ## Conduct Billing Tests and Publish Before your product goes live on GCP Marketplace, it must pass a two-part billing test and final approval. 1. **Run the internal billing test.** After finishing technical and frontend integration in the GCP Producer Portal, notify your Fours Customer Success Manager. The Fours team will run the internal test and authorize a test purchase to ensure data flows correctly. 2. **Run the Google billing test.** Once the internal test passes, log into your GCP console and open a support ticket with GCP Marketplace Support. State that the internal test is complete and request a billing account ID for the external Google Billing Test. Provide the ID to your Fours representative, who will run the external test on your behalf. 3. **Submit a usage record (if applicable).** If your product uses usage-based or metered pricing, submit a test usage record to Google before the listing becomes public. 4. **Make the product live.** Run the Google-provided go-live script to officially publish your listing. This step must be executed by your cloud admin, since Fours does not have permission to trigger it in your GCP project. Once the script runs successfully, your product is live. From this point, you can manage deals, track entitlements, and monitor revenue using the Fours Console. ## Set Product Signup URL Fours automatically syncs with GCP Marketplace and pulls all your listed product info. You can see all your listings on the [Fours Console Product page](https://console.suger.io/product). Select the product listed in the previous steps, click **EDIT** in the `Product Info` section, enter your product Signup URL in the **Fulfillment URL** field, and click **SAVE**. ## Signup URL Redirect 1. After purchasing the product, your buyer is directed to `https://api.suger.cloud/public/signup/gcp/orgId/your-suger-org-id/your-gcp-product-id` first. 2. Then it is redirected to your product Signup URL with two query parameters, `sugerEntitlementId` and `partner`, for example `https://your-product-signup-url?sugerEntitlementId=1234abcd&partner=gcp`. 3. Your service needs to collect this `sugerEntitlementId` and save it with the account created by the buyer. 4. See [how the sign-up URL redirect works](/settings/signup-url-redirect/#how-it-works). ## Login URL Redirect 1. After the buyer has purchased the product and completed the signup process via the [Signup URL Redirect](/gcp-marketplace/list-product#signup-url-redirect), they are redirected to the `login URL` specified in the GCP Marketplace integration, as shown below. > Login URL field in the GCP Marketplace integration settings 2. If the `login URL` in the GCP Marketplace integration is empty, the `Fulfillment URL` in Product will be redirected to. ## Track Consumption with Labels SaaS products with a hybrid architecture require [integration with user labels](https://cloud.google.com/marketplace/docs/partners/integrated-saas/partner-consumption-tracking) to understand how the ISV solution impacts Google Cloud infrastructure consumption in the customer's project. This type of architecture includes a data plane in the customer's Google Cloud project and a control plane in your Google Cloud project. This data gives Google insights into your product's impact in terms of its associated customer Google Cloud usage, which Google can use to showcase impact and guide go-to-market (GTM) investments. ### Step 1 — Request a consumption tracking label For each product that you offer through Cloud Marketplace, you must request a label and then integrate it into your product. To request a label, complete the [Partner Consumption Tracking Initiative form](https://docs.google.com/forms/d/e/1FAIpQLSdPVGiG4P7Dp7BtcgxMoas0QY3-35FW4Wx0xM_jx1nzRcBrWw/viewform). After you complete the form, you receive an automated email with the label that you must integrate with your product. ### Step 2 — Integrate the tracking label with your SaaS product There are four methods to add the consumption tracking label to the resources that your product deploys. The detailed guidance for Terraform can be found in the [Google Cloud Provider Configuration Reference](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#default_labels). For information about adding labels by using the Google Cloud console, Google Cloud CLI, or the REST API, see [Create resources with labels](https://cloud.google.com/compute/docs/labeling-resources#create_resources_with_labels). - Terraform (recommended ✅) - The Google Cloud console - Google Cloud CLI - REST API :::caution Cloud Deployment Manager was discontinued by Google on **March 31, 2026** and can no longer be used. If you still have deployments defined with it, migrate to **Terraform** (recommended) or **Infrastructure Manager**. ::: ## Update a Product Listing What you can change from Fours depends on your listing's status. In `Draft`, the listing is private to Fours and you have full access to pricing, plans, and previews before submitting to GCP. Once a listing is `Published` / `Live`, most content changes must be made in the GCP Producer Portal — from Fours you can still update the fulfillment URL and create private offers. | Status | Visibility | What you can edit in Fours | | --- | --- | --- | | `Draft` | Private (Fours only) | Full access — pricing, plans, draft, and preview before submitting to GCP | | `Published` / `Live` | All GCP buyers | Fulfillment URL and private offers. All other changes must be made in the GCP Producer Portal. | ### Update the fulfillment URL :::info You must have Admin or Editor access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. ::: 1. Go to the **Product** menu in the [Fours Console](https://console.suger.io/product). 2. Open the relevant GCP listing. 3. Click **More actions** in the top right corner, then **Edit Fulfillment URL**. ![GCP Fulfillment URL in the Fours Console](images/update-your-gcp-marketplace-listings-1.webp) 4. Make your adjustments and click **Save** to sync the changes to GCP. ### Edit core listing details in the GCP Producer Portal Editing a live GCP Marketplace listing's descriptions, pricing, or metadata must currently be done directly in the **Google Cloud Producer Portal**, not via the Fours Console. Google reviews Product Details, Pricing, and Technical Integration separately, so approvals may happen at different times. **Prerequisites** - Access to the Google Cloud Producer Portal. - Editor or Owner permissions on the project and listing. - A published GCP Marketplace listing. **Steps** 1. **Log in to the GCP Producer Portal** — navigate to [https://console.cloud.google.com/producer-portal](https://console.cloud.google.com/producer-portal) using your Google Cloud credentials with the proper permissions. 2. **Locate the product listing** — on the main dashboard, find your product under **Your listings** and click the listing you want to edit. 3. **Choose the section to edit** — available sections include: - **Overview** — product name, logo, descriptions. - **Plans & Pricing** — pricing tiers, SKUs, metering setup. - **Technical Setup** — URLs, onboarding flow, containers/images. - **Support & Documentation** — links to help content, privacy policy, and EULA. 4. **Make edits and save** — click into the specific section, edit the fields as needed, and click **Save**. 5. **Submit for review** — navigate to the **Publish** tab and click **Submit for Review**. See [Publish your SaaS product](https://docs.cloud.google.com/marketplace/docs/partners/integrated-saas/submitting) for full instructions. :::info After submitting edits, Google typically takes **2–5 business days** to review and publish the changes. ::: ### Change a listing's visibility Visibility changes can't be made from the Fours Console. They must be done directly in the GCP Producer Portal. - **Publish a listing publicly** — see [Publish your SaaS product](https://docs.cloud.google.com/marketplace/docs/partners/integrated-saas/submitting). - **Deprecate or remove a live listing** — see [Delete a product](https://docs.cloud.google.com/marketplace/docs/partners/deprecate-product). ## FAQ ### How long does the GCP listing approval process take? The GCP approval process typically takes 1–3 weeks and involves multiple sequential steps: product details review, pricing approval, and technical validation. Unlike AWS, where everything can be submitted at once, GCP requires each stage to be completed before moving to the next. Plan for extended timelines, especially during busy periods. ### Why do I have to configure my listing in the GCP Producer Portal instead of the Fours Console? Due to strict GCP API limitations, third-party platforms like Fours can't fully automate listing creation, description updates, or pricing modifications. You must complete your core product details natively in the GCP Producer Portal. Once live, Fours acts as your central command center for generating private offers and tracking revenue. ### Why does the GCP approval process take multiple steps? GCP requires a sequential approval workflow where content changes, pricing updates, and technical integration are submitted and approved separately. You can't bundle these changes together, and each phase can take several days to weeks for Google's review team to approve. ### Why does my listing show different statuses in Fours vs. GCP Marketplace? GCP's API provides limited real-time status updates compared to other marketplaces, so there can be sync delays between what Google reports and what appears in Fours. Always check the GCP Producer Portal for the most current listing status, and contact support if you see persistent discrepancies. ### I don't have permission to make changes to our GCP listing. How do I get access? GCP Marketplace permissions are managed separately from Fours. Ask your GCP admin or IT team to grant you "Marketplace Publisher" permissions in your Google Cloud Console. ### How do I update pricing on my GCP listing without affecting existing customers? Pricing changes must be submitted through the GCP Producer Portal and go through Google's review process — you can't make instant pricing updates. Plan for 1-2 weeks of approval time. Existing customer contracts typically remain at their original pricing terms until renewal. ### Do I really need to enter a public price if I only want to sell via private offers? Yes. GCP uses a base-plan structure, meaning every private offer must be built upon an approved public plan. However, you can submit an artificially high placeholder price and hide the plan from public view: - **Placeholder price** — enter any number that satisfies GCP's requirement. This doesn't have to be the price your enterprise buyers will pay. - **Hidden visibility** — you can hide all public pricing on your listing. - **"Talk to Sales" experience** — hiding public pricing automatically sets the listing to "Talk to Sales," giving your team flexibility to negotiate private offers. ### Is a Google Cloud Validated Solution designation required to list in the marketplace? Yes, it is required. ### I saw a company on GCP that lists no pricing; they default to "talk to sales." Is it common for vendors not to disclose pricing? You can hide all your pricing plans in the public GCP Marketplace listing. Some of our clients have this configuration. It is a very common strategy in the B2B SaaS industry, giving sales more flexibility to negotiate deals. It is relatively straightforward to configure. ### Why is the IAM binding setting the principal to "allUsers" instead of a specific group or service account? Setting it to "allUsers" makes the listing publicly live, so any GCP client can view, purchase, and subscribe to your listing service. --- Source: https://doc.fours.com/gcp-marketplace/create-private-offer/ # Create Private Offer Create a custom offer for a specific customer in GCP Marketplace, allowing flexible pricing and contract terms tailored to your buyer's needs. --- ## Overview With Cloud Marketplace Private Offers, you can create a custom offer for a Kubernetes app, SaaS product, or virtual machine (VM) image for a specific customer. The offer enables your customer to purchase your Cloud Marketplace product at a negotiated price or discount. :::danger When the customer opens their offer, they are taken to a purchase page on Cloud Marketplace. The customer then confirms the purchase and signs up for your product. After sign-up, they use your product as if they signed up for a plan directly through Cloud Marketplace. ::: A private offer consists of: 1. **Product Plan**: The base plan for the offer. Each plan uses a single [Product Pricing Model](/gcp-marketplace/pricing-model/). 2. **Private Offer Pricing Model**: Customizes the Product Pricing Model for the selected plan. (Note: One Product Pricing Model can have multiple Private Offer Pricing Models.) 3. **Payment Schedule**: Defines how and when the customer pays (Prepay or Postpay). 4. **Contract Duration**: The length of time the offer is valid. --- ## Prerequisites Before you proceed, make sure both your GCP and Fours environments are ready. This prevents errors during offer creation and approval. **Google Cloud Marketplace** — collect the following buyer information: - Exact GCP Billing Account ID - Organization Name - Contact Name and Contact Email **Fours** — you need **Admin** access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). --- ## Create the Offer in Fours Console ### Step 1: Open the private offer flow 1. Go to the **Offer** page in the [Fours Console](https://console.suger.io/offer). 2. Click **+ New Private Offer** in the upper-right corner. 3. Select the **GCP Product** you want to base the offer on. This defines what is being sold. :::tip Start from an existing offer To reuse an existing offer's details, open it and choose **More actions → Clone Offer**. The form opens pre-filled from that offer. This includes an offer created in Producer Portal and synced into Fours: its GCP Billing Account ID, Organization Name, contact details and notes carry over into the clone. Cloning a private offer also carries over its **Configure Auto-Renew** setting, its **Number of renewals** and its EULA; cloning a professional-services offer carries over its statement of work. For an offer built in Producer Portal, Fours records that EULA and statement of work when it syncs the offer with **Enable PrivateOffer API** on — see [About Enable PrivateOffer API](/gcp-marketplace/integration/#about-enable-privateoffer-api). A reseller's offer (`CPPO`) and an incoming resale authorization (`CPPO_IN`) cannot be cloned. ::: When you clone a private offer or a replacement offer that is still **Pending Acceptance**, the form also shows an **Existing offer** card with **Cancel the existing offer at the publishing of this offer**, checked by default. Leave it checked and Fours cancels the original as soon as the new offer reaches pending acceptance, so your buyer is not left with two live offers; a subscription the buyer already accepted is not affected. Fours cancels the original through the path your integration uses at that moment — see [About Enable PrivateOffer API](/gcp-marketplace/integration/#about-enable-privateoffer-api). That includes an offer someone built in Producer Portal and Fours picked up by syncing. ### Step 2: Add basic information - **Offer Name** — A descriptive title for your offer. Use a clear, consistent format, such as `CustomerName - ProductName - MM/YYYY`. - **Salesforce Opportunity / HubSpot Deal** — Optional dropdowns that link this offer to an active deal in your CRM. This automatically syncs the offer's status back to your sales pipeline so your team can track it without leaving Salesforce or HubSpot. - **GCP Billing Account ID** — The exact, unique identifier for the customer's Google Cloud billing account. This must be completely accurate — ask your buyer to provide it directly from their GCP console. - **Organization Name** — The name of the buyer's company or organization (for example, `Acme Corp`). - **Contact Name & Contact Email** — The name and email of the primary buyer contact who will review and accept the offer. - **Notes for Customer** — Any additional instructions, context, or welcome messages you want the buyer to see when they open the offer. - **(Sales info) Contact Name & Email** — The internal sales representative managing this offer. This usually auto-fills with your own Fours login details. - **Notes for Your Team** — Internal notes visible **only** to your team. The buyer never sees this, so it's the place to track internal approvals, deal context, or special instructions. - **Internal Notes** — A separate optional Fours-side note, team-only and up to **1,000 characters**, never shown to the buyer. It matches the **Internal Notes** field on the AWS and Azure offer forms, and is in addition to **Notes for Your Team** — both are team-only. ### Step 3: Set pricing information The fields in this section change depending on the plan type you select. Start with your plan, then work through the fields that appear. - **Plan** — The specific service tier the buyer is purchasing. - **Payment Recurrence** — Choose how often the buyer is billed: - **Monthly, Quarterly, or Yearly** — Standard recurring (Postpay) billing. The buyer is charged at the end of each period after the service is delivered. Auto-Renew is supported with these options. - **Custom** — Build a custom installment schedule with specific dates and amounts (GCP's Prepay model). The first installment is charged when the buyer accepts, so it shows **Acceptance Date** instead of a date. Auto-Renew is not available with this option. - **Expiry Date** — The deadline for the buyer to accept the offer. If this date passes without acceptance, the offer becomes void. Google allows at most **3 months**: the latest date you can pick is today plus three months, minus one day, on Google's Pacific calendar. A later date is refused when you create or submit the offer, before anything reaches Google, with a message that names the date you picked and the last date you can use — for example, *"the offer expiration date (January 5, 2027) is too late. Google Cloud Marketplace requires offers to expire within 3 months, so choose a date on or before December 22, 2026"*. Saving a draft does not check the date. - **Enable future start date** _(optional)_ — Toggle on if you want the contract to begin on a specific future date rather than immediately upon acceptance. Useful for aligning with a buyer's budget cycle. - **Offer Duration** — The length of the contract, counted in the payment recurrence's own unit: months for **Monthly** and **Custom**, quarters for **Quarterly**, years for **Yearly** (for example, `12` months, `4` quarters or `1` year for a one-year deal). Counted in months, an offer can run from 1 to 84 months. - **Proration** — Appears only with **Monthly** recurrence, and not for the **Usage Discount Only** pricing model. **Off** (the default) keeps every installment on the offer's anniversary date; **On** prorates the first installment against the start date so billing lines up with calendar months. Fours always sends your choice to Google, so Google's own plan default never decides it. A cloned offer keeps the setting, and the offer detail page shows it as **On**, **Off** or **Not set (GCP default)**. - **Configure Auto-Renew** — Appears with **Monthly**, **Quarterly** and **Yearly** recurrence. Switch it **On** to let the buyer decide whether the contract's pricing and terms auto-renew, then set the required **Number of renewals**, which starts at **1**: the number of times the buyer can renew on the current term, unless an amendment is accepted. Google caps the first term plus every renewal at 84 months, so the most renewals you can set is the remaining months divided by the term, rounded down — **6** for a 12-month offer, **20** for a 4-month offer — and an offer longer than 42 months cannot auto-renew. The form checks the count as you type and again when you submit: - *Please enter the number of renewals.* — the field is empty. - *The number of renewals must be a whole number of at least 1.* — the count is zero, negative or a fraction. - *Maximum number of renewals allowed based on the offer duration is 6.* — the count is higher than the term allows; the message names the most it allows (here, for a 12-month offer). - *A 48-month offer can't auto-renew. Shorten the duration to 42 months or less, or turn off auto-renew.* — the term is longer than 42 months. Switching it **Off** removes the count. On a **Usage Discount Only** offer, Fours turns auto-renew off when you submit. Creating the offer from Salesforce instead? See [Auto Renew (GCP)](/salesforce-app/salesforce-app-offer/#auto-renew-gcp). The remaining pricing fields depend on the plan type. For the full breakdown of pricing models and how discounts apply, see [Subscription-Based Offers](#subscription-based-offers), [Usage-Based Offers](#usage-based-offers), and [Subscription + Usage Combined](#subscription--usage-combined) below. - **Subscription plans** — Enter the **Monthly Flat Fee**, the fixed monthly amount the buyer pays. No usage fields apply. - **Usage plans** — Select the **Usage Plan Pricing Model** (required), then set the **Monthly Commitment** and **Discount on Commitment** as applicable to the chosen model. The dropdown groups the models the way Producer Portal does, with a one-line hint under each: **Committed use discounts** holds *Commitment discount with additional usage at list price* and *Commitment with all usage discounted*, and **Usage Only** holds *Usage-based discount only*. - **Subscription + usage plans** — Enter the **Monthly Flat Fee** (base fee), **Discount on Usage** (percentage discount on metered consumption beyond the base fee; leave blank if none), and any **Additional Usage Fee**. The **Metric discounts** table updates automatically to show the tier breakdown, list price, and discounted price per unit. - **Free plans** — Enter `$0` or leave the **Monthly Flat Fee** blank, and `0%` for **Discount on Usage**. Free plans do not generate software charges. :::info Amounts cannot be negative GCP rejects a negative amount outright, so Fours catches it on the form instead of at submit time. A negative commit amount reports **"The amount must be 0 or greater."**, and a negative installment names the row it is on — for example "The amount of payment installment 2 must be 0 or greater." Zero is allowed; a free offer is perfectly valid. ::: ### Step 4: Define other information - Select an **EULA** to define the end customer license agreement. If you choose your own EULA, upload its file: until you do, **Create offer** stays greyed out and its tooltip names **Custom EULA File**. - Select a **Deal Type** to define the commercial structure of the offer. Fields marked with an asterisk (*) are required, and which ones depends on your choices — **Usage Plan Pricing Model**, for example, only for a usage plan. **Create offer** stays greyed out while a required field is empty or a value isn't valid. To see what's left, hover over the button, or press Tab until it has focus: its tooltip, headed *Please complete:*, lists each step that still needs work and the fields in it — for example, *Step 2 Pricing information — Expiry Date* — with the reason beside any value that isn't valid. A value that isn't valid is also outlined in red, with the reason beneath the field. Then click **Create offer** to publish the private offer. ### If the buyer already has an active offer Google allows one live offer per product for a billing account, unless the product is enrolled in Multiple Orders (see [Multiple Flat Fee Offers](#multiple-flat-fee-offers)). So before anything reaches Google, Fours checks whether the billing account already holds an active entitlement on the same product, whatever its pricing model. It checks every buyer that shares the billing account — one Cloud Billing account can hold several GCP accounts, and each is its own buyer in Fours. An entitlement on public list pricing doesn't count, because a private offer is how you replace one. When the private offer form — for a new offer or a clone — finds one, it asks before going further. An **Another active offer exists for this buyer** dialog says *"There is already an active offer on this product for this billing account."* and shows: | Row | What it shows | | --- | --- | | **Product** | The product of the new offer. | | **Billing account** | The buyer's Cloud Billing account ID. | | **Buyer** | The buyer that holds the live offer, by name and Fours ID. | | **Active offer** | The live offer's name and, when it has a fixed end, the date it is **valid through** — with a **View existing offer →** link that opens it in a new tab, so the form behind the dialog stays as you left it. | - **Cancel** — return to the form, for example to start a [replacement offer](#replacement-offer) from the existing offer instead. - **Continue create** — create the new offer anyway. Use it when the product is enrolled in Multiple Orders; otherwise Google requires you to amend the existing offer. The professional-services and replacement offer forms don't ask. They show a toast instead, *"Can't create offer — active offer already exists"*, naming the buyer, the product, the billing account and the existing offer, with an **Open existing offer →** button that takes you straight to it. ### Coterm and standard billing intervals An offer billed at a **standard interval** — monthly, quarterly, or yearly — cannot also carry a scheduled end date. Google refuses the combination, so Fours reports it as a validation error on submit rather than accepting the offer and failing it moments later. This matters most for coterm-aligned replacement offers, where you want the new offer to end when the offer it replaces ends. On a standard interval, express that as an **offer duration** instead of an end date. Offers on a custom billing period are unaffected and may carry an end date as before. On the private offer and professional services forms, when the form asks for **Offer Duration** rather than an **End Date**, Fours drops any end date the draft still carries — one copied from the offer you cloned, or one saved before you changed the payment recurrence — so the duration you entered is the one Google receives. ### If the offer does not get created When Fours cannot finish creating and publishing the offer, it lands in `Create Failed`. Either Google refused a request, or Fours' own checks stopped the create before anything was created in Google — for example a custom EULA file Fours cannot read, or pricing it cannot map to your plan. The offer's detail page shows a **Create Offer Failed** alert with the reason, and keeps its **Edit Draft** and **Submit** actions: fix what the message names and submit the same offer again, without rebuilding it. If you would rather abandon the offer, you can archive it. An older offer may show `Invalid` for the same kind of refusal. **Submit** does not work on an `Invalid` offer: open **Edit Draft**, fix what the alert names and choose **Save as draft**. The offer becomes a `Draft` again, and **Submit** works on it. When you create an offer through the API with **Enable PrivateOffer API** on, two pricing combinations that Google's API cannot express are refused when you submit, instead of landing in `Create Failed` a moment later — on a replacement offer too. A metric discount on **Commitment discount with additional usage at list price** is refused with *"remove the metric discounts. This plan has no usage price for them to discount"*. A **Custom** payment recurrence on **Usage-based discount only** is refused with *"use monthly payment recurrence instead of custom. A usage-discount-only offer has no commitment for installments to charge"*. The console and Salesforce offer forms never offer either combination. #### Resubmit after a failed publish With **Enable PrivateOffer API** on, a create that got as far as Google can leave an unpublished draft of the offer there. When you submit the offer again, Fours checks that draft first instead of creating a second one: ```d2 direction: down submit: "You submit a Create Failed offer again" draft: "Did an earlier attempt leave\na draft in Google?" { shape: diamond } state: "What does Google\nshow for it now?" { shape: diamond } create: "Create the offer in Google" rewrite: "Rewrite the draft with\nthis submission" publish: "Publish the offer" stop: "Submit fails\nGoogle's state is recorded on the offer" submit -> draft draft -> create: "no" draft -> state: "yes" state -> rewrite: "still a draft" state -> create: "deleted, cancelled\nor expired" state -> stop: "publishing, published,\naccepted or ended" create -> publish rewrite -> publish ``` - **Still a draft** — Fours rewrites the draft with the offer as you submitted it this time, including any field you cleared, and publishes it. No second draft is left behind. - **Deleted, cancelled or expired** — Fours creates the offer afresh. - **Publishing, published, accepted or ended** — the offer is, or was, live in front of the buyer, so Fours neither rewrites it nor creates a second offer beside it. The submit fails, and the offer records the state Google reported. While Google still shows the offer as a draft, Fours' sync leaves it alone, so the sync cannot overwrite the edits you made to fix it. The offer's **GCP Billing Account ID** shows the account you saved, even while Google still holds the draft with the old one. --- ## Share the Offer Once you click **Create**, the offer is securely sent to Google for a brief review before it can be shared with your customer. Here's how to track, share, and finalize the deal: 1. **Check the status.** Your offer initially shows as `Pending Google Approval`. Wait a few minutes and refresh until the status updates to `Created` — this means the offer URL is officially ready. 2. **Copy the offer link.** Open the created offer, then click **Copy offer URL**. ![GCP Copy Offer URL](images/create-a-gcp-marketplace-private-offer-1.png) 3. **Send to the buyer.** Share the link with your buyer so they can log into their GCP account, review the custom terms, and confirm the purchase. See [Accept Private Offer](/gcp-marketplace/accept-private-offer/) for the buyer's steps. 4. **Provide final approval.** For SaaS products, once the buyer accepts the offer, the status changes to `Needs Your Approval`. You must confirm the offer to activate it, unless you have Automatic Offer Approval enabled. The offer detail page also shows an **Offer Duration** row alongside the dates, so you can confirm the contract length that was sent to Google without reopening the form. Those dates — **Expire Date**, **Accept Date**, **Start Date** and **End Date** — are shown in Pacific time with a PST or PDT label, for every viewer, and so are a GCP entitlement's start and end dates on its page and in the Entitlements table. That matches Producer Portal, because Google anchors a private offer's term on the Pacific calendar day. An active entitlement's end date follows its offer's term: if the two have drifted apart — usually by a day — Fours moves the entitlement's end date to match on its next sync. --- ## Enable Automatic Offer Approval By [enabling automatic offer approval](https://console.cloud.google.com/producer-portal/private-offers/settings), you can use scheduled or customer-acceptance start dates for SaaS product first offers. You can create or edit an offer's start date under **Start date**. Kubernetes and VM offers already have flexible start dates. > ![Automatic Offer Approval](https://imagedelivery.net/pNNvR2_tZYczcQ3leBU_1A/63f49488-3477-4394-8f51-f891fc2dd500/square) --- ## Multiple Flat Fee Offers :::tip Google Cloud Marketplace supports multiple **flat fee offers** for a single buyer. You can have several active private offers with the same customer, each with its own terms and duration. ::: **To enable Multiple Flat Fee Offers:** 1. Go to the [GCP Producer Portal](https://console.cloud.google.com/producer-portal/private-offers/settings) 2. Select the **Multiple Orders** tab 3. Choose your product 4. Click **Enable Multiple Orders** > ![Enable Multiple Flat Fee Offers](images/gcp_enable_multiple_flatfee_orders.jpg) --- ## Payment Schedules: Prepay vs Postpay | | **Prepay** | **Postpay** | | ------------- | ----------------------- | ----------- | | Contract Term | 1–84 months | 1–84 months | | Auto Renew | Not supported | Supported | | Notes | Not available in Brazil | | --- ## Subscription-Based Offers For subscription-based product plans, only the **Flat fee** pricing model is available, with Prepay or Postpay options. | | :moneybag: **Flat fee** | | ------- | :------------------------------------------------------------------------------------------------------------------------------------- | | Prepay | Customize:
  • Contract duration (months)
  • Installment schedule
![Prepay Example](images/subscription_prepay.png) | | Postpay | Customize:
  • Contract duration (months)
  • Monthly flat fee
![Postpay Example](images/subscription_postpay.png) | --- ## Usage-Based Offers For usage-based product plans, three private offer pricing models are available. The first two are types of [Committed Use Discount (CUD)](#committed-use-discount-cud): - **Commit discount with additional usage at list price** - **Commit with all usage discounted** - **Usage discount only** Each model supports Prepay or Postpay (except Usage discount only, which is Postpay only). ### Commit Discount with Additional Usage at List Price The customer commits to a minimum spend and receives a discount on this commitment. Overage is charged at list price. | | :moneybag: **Commit discount with additional usage at list price** | | ------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Prepay | Customize:
  • Contract duration (months)
  • Installment schedule
  • Discount on commitment
![Prepay Example](images/usage_commit_list_price_prepay.png) | | Postpay | Customize:
  • Contract duration (months)
  • Monthly commitment
  • Discount on commitment
![Postpay Example](images/usage_commit_list_price_postpay.png) | ### Commit with All Usage Discounted The customer commits to a minimum spend and receives a discount on all usage, with optional granular discounts per usage metric. | | :moneybag: **Commit with all usage discounted** | | ------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Prepay | Customize:
  • Contract duration (months)
  • Installment schedule
  • Discount on usage
  • Specific discount per usage metric (optional)
![Prepay Example](images/usage_commit_all_discounted_prepay.png) | | Postpay | Customize:
  • Contract duration (months)
  • Monthly commitment
  • Discount on usage
  • Specific discount per usage metric (optional)
![Postpay Example](images/usage_commit_all_discounted_postpay.png) | ### Usage Discount Only The customer pays a discounted rate for usage, with no commitment. Only Postpay is supported. | | :moneybag: **Usage discount only** | | ------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Prepay | Not applicable | | Postpay | Customize:
  • Contract duration (months)
  • Discount on usage
  • Specific discount per usage metric (optional)
![Postpay Example](images/usage_discount_only_postpay.png) | #### Committed Use Discount (CUD) With a CUD, the customer receives a discount in exchange for a minimum spend commitment. The customer pays the commitment regardless of usage. The difference between the two CUD models is whether the discount applies to overage. > ![CUD Comparison](https://user-images.githubusercontent.com/98442625/212490181-7a04b23d-1888-432b-9a9d-7c5e003e2cff.png) ##### Free credit and unused commitment (Prepay CUD only) On a **Prepay** CUD offer — either **Commit discount with additional usage at list price** or **Commit with all usage discounted** — two extra controls appear above the payment-installment rows. They are schedule-wide choices that change the columns on the rows below, and they exist only on these plans because GCP models both on the commitment itself. **Free credit** Turn the **Free credit** switch on to grant a one-time credit on top of each installment's commitment balance, then enter the amount per installment. Turning the switch back off clears any credit already entered. On a replacement offer, installments that are already locked stay read-only here, the same as their amount and discount. **Which type of unused commitment rule would you like to apply?** This decides what happens to an installment's unused commitment — and to any partner-sponsored free credit — when the next installment starts: | Rule | Effect | | ---- | ------ | | **Rollover** | The unused balance carries into the next installment. This is GCP's default. | | **Expire** | The unused balance is discarded at the start of each following installment. | | **Custom** | Decide per installment. Each row gains an **Expire** checkbox that governs the transition into the *next* row. | The first installment never discards anything, since nothing precedes it. :::warning Expire discards free credit too "Expire" is not limited to the commitment. All unused and carried-over commitment **and partner-sponsored free credit** expire together. If you intend the credit to survive, choose **Rollover**, or use **Custom** and leave the relevant transitions unchecked. ::: The offer's detail page carries read-only **Free Credit** and **Unused Commitment** columns on its payment-installments table, so you can confirm what was actually sent to GCP. They appear on different conditions: **Free Credit** only once an installment actually carries a credit, while **Unused Commitment** appears on **every committed-use offer** — both CUD models, whichever rule you chose, **Rollover** included. It shows up whether the offer was created through the Commerce Producer API or the browser-driven path, because a commitment on the installments answers the same question as the stored pricing model. Each row of that column reports what happens to the balance *leaving* it, matching both the GCP producer portal and the **Expire** checkbox on that row. The last row therefore always reads "Expire all at offer end date": the term ends there, so nothing can roll further. ![The Prepay CUD payment-installments section — the Free credit switch turned on and the Rollover / Expire / Custom segmented control on the row above, and an installment table that gains a per-row Free credit input once the switch is on](images/72-prepay-cud-installments.png) --- ## Subscription + Usage Combined If your customers pay both a flat fee and additional usage charges, use the **Flat fee with usage discount** model. The flat fee includes a usage allowance; overage can be discounted. | | :moneybag: **Flat fee with usage discount** | | ------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Prepay | Customize:
  • Contract duration (months)
  • Installment schedule
  • Discount on usage
  • Specific discount per usage metric (optional)
![Prepay Example](images/flat_fee_usage_discount_prepay.png) | | Postpay | Customize:
  • Contract duration (months)
  • Monthly flat fee
  • Discount on usage
  • Specific discount per usage metric (optional)
![Postpay Example](images/flat_fee_usage_discount_postpay.png) | --- ## Metric Discounts Display When creating a private offer for a plan that includes usage fees, you can view a detailed breakdown of how discounts apply to each usage metric and pricing tier. :::tip Metric discounts are available for **Usage-based** and **Subscription + Usage** plans. They are not calculated for pure subscription plans, nor for the "Commit discount with additional usage at list price" model — in that model the discount applies to the commitment amount, never to the individual usage metrics. ::: :::note "Commit discount with additional usage at list price" on the offer detail page A committed-use-at-list-price offer that has payment installments always shows its per-installment metric breakdown once the offer exists, even though no discount was applied to those metrics. That is the point: the breakdown is what shows the buyer, installment by installment, that their additional usage is billed at list price. The installment's discount percentage discounts the commitment, so the metric rows read as list price throughout. ::: ### How It Works After entering a discount percentage, click the **Metric discounts** button to expand a detailed pricing table. The table shows, for each usage metric: - **Metric name** (e.g., "API Calls", "Storage GB") - **Tier information** — tier label, count range, list price per unit, and discounted price per unit Discounted prices are calculated in real time as you adjust the discount percentage. **Postpay:** The metric discounts section appears below the discount percentage input. > ![Metric Discounts Postpay](images/metric_discounts_postpay.jpg) **Prepay:** The metric discounts appear per payment installment, since each installment can have a different discount percentage. > ![Metric Discounts Prepay](images/metric_discounts_prepay.jpg) ### On the offer detail page Once Google has created a **Prepay** offer, its **Usage Dimensions** table shows what each metric is billed at, in the **Price per Dimension** column: - **The same discount on every installment** — the discounted price, with the discount and the list price beneath it; for example **USD 1.50** above *62.5% off USD 4.00*. - **A discount that differs between installments** — the list price and a **List price · discounted, varies by installment** link. The link expands every row of the payment-installments table and scrolls to it, where each installment's discounted price is listed. An offer Google hasn't created yet, such as a draft, shows list prices, and so does a metric on **Commit discount with additional usage at list price**, whose discount applies to the commitment. Postpay offers keep their separate metric discounts section. --- ## Custom Feature List When creating a private offer for a subscription-based plan (**Subscription** or **Subscription + Usage**), you can customize the feature list to tailor it for a specific deal — without changing the underlying product plan. ### How It Works 1. Select a subscription-based pricing plan. The feature list automatically populates with the plan's default features. 2. Click the **Update features** button to open the edit dialog. 3. For each feature, choose a status: - **Included** — feature is included in the offer - **Not Included** — feature is excluded - **N/A** — not applicable - **Add Details** — enter custom text (up to 100 characters) 4. Click **Save** to apply your changes. Modified features are marked with a checkmark icon. > ![Custom Feature List](images/custom_feature_list.jpg) > ![Custom Feature List Edit Dialog](images/custom_feature_list_edit.jpg) --- ## Replacement Offer A replacement offer lets you renew or upsell an active entitlement. Once accepted, the buyer's entitlement is updated immediately. :::tip You cannot change the product, plan, or price model of the existing private offer. You can only change payment schedule, amount, discount, and duration. ::: **Required info:** - **Expiry Date**: The deadline for the buyer to accept the replacement. As with any GCP offer, it can be no later than today plus three months, minus one day, on Google's Pacific calendar — and the rule below about the existing offer's installments can require an earlier date. - **Start Date**: When the new offer begins (can be a future date; defaults to immediate after acceptance). - **Payment Schedule**: Prepay or Postpay (can differ from the original offer). - **End User License Agreement (EULA)**: Select or upload your custom contract. The replacement starts from the replaced offer's EULA choice; if that is a custom EULA, upload its file for the replacement, because the offer cannot be created without it. :::warning The expiry or start date must be before the first future payment installment date of the existing offer. ::: **A co-terming replacement cannot start after the term it co-terms to has ended.** When the replacement is set to co-term to the replaced offer, its **start date** must fall on or before the last live day of that term — Fours rejects a later date and names the latest start date you can use. The check is skipped when the replaced entitlement is already pending cancellation: in that case the replaced term's dates are all in the past and no start date could satisfy the bound. ### When to replace instead of creating a new offer If you start a **new** offer on a product the buyer is already live on, Fours asks first — see [If the buyer already has an active offer](#if-the-buyer-already-has-an-active-offer). Choose **Cancel** in that dialog to build a replacement offer instead. A replacement offer is usually the right choice when you are renewing or upselling the same buyer, because it updates the existing entitlement rather than leaving two offers side by side. You can also amend an accepted offer that has **no entitlement yet** — Fours links the new offer to the live base offer directly, so you don't have to wait for the entitlement to appear. :::info Native Renewal eligibility GCP treats a replacement as a **Native Renewal** only when the entitlement it replaces ran for at least **9 months**, and — if that entitlement has already expired — the replacement comes within **90 days** of its expiration. When those rules are not met, Fours falls back to a **New** deal type and records a warning on the offer rather than failing the create. Integrations that create entitlements from offers (MaaS) are exempt: GCP applies neither the minimum-duration nor the post-expiration rule to them, so a Native Renewal selection is left as you set it. ::: ### Why a replacement offer was refused Before creating anything, Fours asks Google whether this replacement is allowed and which offer it must replace. If the answer disagrees with what you selected, the offer is refused up front and **nothing is created** — no half-made offer to clean up. Each refusal names the specific problem and what to do next: | What Google said | What to do | | --- | --- | | The marketplace requires this offer to replace a **different offer** than the one you selected. The message shows both. | Sync GCP offers for this integration, then start the replacement from the customer's current offer. | | The offer you selected to be replaced **isn't eligible** for this customer. The message lists the offers that are. | Start the replacement from one of the listed offers, or create a new offer alongside the existing ones. | | The customer's active order is on **public list pricing**, so the marketplace requires the public offer to be replaced rather than a private one. | Fours cannot create that offer type yet. Create it in the Google Cloud Marketplace console, or contact Fours support. | | The customer has **no active order** for this product, and the marketplace only accepts a replacement when they do. | Create a standard private offer instead. | | The customer **already has an active order**, and the marketplace requires a replacement rather than a new offer. The message names their current offer. | Start a replacement offer from this customer's entitlement. | | The offer is set to end when the offer it replaces ends, but **that offer's end date isn't known**. | Sync GCP offers for this integration, or set an explicit end date on this offer. | | Fours **couldn't confirm** with the marketplace which offer this one should replace. | Usually temporary — try again shortly. If it persists, contact Fours support. | | The marketplace **did not allow** Fours to look up which offer this one should replace. | A configuration problem, not an offer problem; retrying will not help. Ask an administrator to check the GCP integration's permissions, then submit again. | | The marketplace **could not accept the lookup** for this customer. | Usually a missing customer billing account on the offer. Check it, then submit again. | Fours also refuses a replacement it cannot tie to the offer being replaced, before asking Google anything. The form stops with *"Could not determine the offer being replaced. Reload the entitlement and try again."* — reload the entitlement and start the replacement from it again. The create API refuses the same request, so nothing is created. Fours likewise refuses to replace an offer that has already ended on GCP — expired, cancelled, lapsed, or failed approval — because Google no longer accepts it as the offer to replace. When you submit, the form stops with *"The offer you are amending ({offer ID}) has already ended on GCP and can no longer be replaced. If this buyer has an active successor offer for the same billing account, amend that one instead — otherwise create a new offer."* While Google is still settling the offer's state, the message names the state instead — for example *"… is in state OFFER_EXPIRED on GCP and can no longer be replaced. …"* An entitlement that is **pending cancellation** is the exception: its offer has run its term, but you can still amend it. The create API refuses the same request. ### Replacement Offer: Prepay - **Payment Installment**: Specify amount, discount, and date for each installment (past installments cannot be changed). - **Offer End Date**: Must be set. > ![Replacement Offer Prepay](images/replacement_offer_prepay.png) ### Replacement Offer: Postpay - **Monthly Flat Fee**: Set the monthly fee. - **Discount on Usage**: Set the usage discount. - **Configure Auto-Renew**: Starts from the replaced offer's setting and **Number of renewals**, so an amendment doesn't silently turn renewal off. The same limits apply as on a new offer — see [Step 3](#step-3-set-pricing-information). - **Offer Duration**: Set duration in months. - **Proration**: Inherited from the offer being replaced and read-only, because Google does not allow changing it on an amendment. It reads **Not set (GCP default)** when the original offer has no recorded setting. > ![Replacement Offer Postpay](images/replacement_offer_postpay.png) --- ## Professional Service Offer Create a private offer for a professional service product, allowing you to tailor pricing, payment schedules, and contract terms for your customer. This section outlines the required information and available payment options. **Required information:** - **Offer Name:** Name of the private offer - **GCP Billing Account ID:** Buyer's billing account - **Organization Name:** Buyer's organization - **CustomerContact:** Buyer's name and email - **Provider Contact:** Your sales contact's name and email - **Plan:** Select the price plan - **Expiry Date:** The date by which the buyer must accept the offer :::note **Whether a SOW is required is decided by the product, not by the offer form.** For a synced GCP product, Fours reads the professional-services designation from the marketplace listing type — the same thing Google enforces the requirement on. This matters for offers created outside the Console: the Salesforce app and the API submit GCP offers without a product type, so an offer with no SOW used to pass every Fours check and then be rejected by Google after the fact. It is now refused up front, where you can still fix it. ::: - **SOW (Statement of Work):** Attach or reference the SOW agreement - **SOW Name:** (Optional) Name for the SOW - **EULA:** Select or upload your custom contract. A custom EULA needs its uploaded file before the offer can be created. - **Deal Type:** Specify the deal type **Start Date** is the acceptance date unless you turn on **Enable future start date**, and **Offer Duration** — or, for a prepaid offer with a future start date, **End Date** — sets how long the offer runs. **Payment schedule options:** - **Prepay:** Buyer pays on a custom installment schedule - **Installment schedule:** Define payment dates and amounts - **Commit Price:** Set the total committed price - **Discount on Usage:** Specify any usage-based discounts > ![Professional Service Offer Prepay](images/professional_service_prepay.png) - **Postpay:** Buyer pays monthly after service delivery - **Monthly flat fee:** Set the recurring monthly fee - **Discount on Usage:** Specify any usage-based discounts - **Configure Auto-Renew:** Optionally let the contract auto-renew, and set its **Number of renewals** — see [Step 3](#step-3-set-pricing-information) for the limits > ![Professional Service Offer Postpay](images/professional_service_postpay.png) :::tip Ensure all required documents (such as the SOW) are ready before creating the offer. Align payment schedules and contract terms with your customer's procurement process for a smoother experience. ::: ## Virtual Machine Offer Creating a private offer for a VM product enables customized pricing and terms for GCP virtual machines, including Committed Use Discounts. **Step 1: Select Plan** - Select the plan for the private offer. **Step 2: Select Pricing Model** - Once the plan is selected, the Pricing Model options will be displayed. These options mirror the standard usage-based models; select the one that aligns with your deal structure. - **Commit discount with additional usage at list price** - **Commit with all usage discounted** - **Usage discount only** > ![Professional VM Offer](images/gcp_vm_offer.png) :::tip For detailed definitions and calculation logic of these three pricing models, please refer to the **Usage-Based Offers** section above. ::: --- Source: https://doc.fours.com/gcp-marketplace/accept-private-offer/ # Accept Private Offer Guidance to accept the private offer as the end buyer in GCP marketplace --- ## Overview This guide provides step-by-step instructions on how to accept a private offer on Google Cloud Platform (GCP) marketplace. It explains the process of reviewing and accepting the offer, checking the start and end dates, and understanding the usage metrics. It also guides users through the signup process, including filling out the necessary fields and upgrading their account. ## Before you begin To accept private offer in GCP marketplace, you must have the one of following Identity and Access Management (IAM) role(s): - [Billing Administrator](https://docs.cloud.google.com/billing/docs/how-to/billing-access#overview-of-cloud-billing-roles-in-cloud-iam) (roles/billing.admin) **OR** - [Billing User](https://docs.cloud.google.com/billing/docs/how-to/billing-access#overview-of-cloud-billing-roles-in-cloud-iam) (roles/billing.user) AND [Consumer Procurement Order Administrator](https://docs.cloud.google.com/marketplace/docs/access-control#roles-permissions) (roles/consumerprocurement.orderAdmin) If you don't have the correct role(s), request access from a Billing Administrator or Organization Administrator. For information and steps on granting roles, see [Access control](https://docs.cloud.google.com/marketplace/docs/access-control). ## Accept private offer 1. Open the **private offer link** sent from the Fours notification email or sales representative. 2. In the **Review and subscribe** section, review the final details, including the plan policy. To acknowledge the additional requirements, select the checkboxes. 3. Click **Subscribe**. A window appears to confirm your subscription. 4. In the confirmation window, click **View orders** to see the order status for all of your private offers, or click **Go to Marketplace** to browse Cloud Marketplace. 5. Depending on the product, you might need to activate your subscription directly with the vendor. After you subscribe, the vendor is prompted to accept the offer. The offer pricing takes effect on the contract start date, as outlined in the offer. ### Accept offer with auto-renew If the vendor has configured auto-renew, you can enable the private offer to automatically renew at the end of the contract. If you turn on auto-renew, the renewed offer uses the same contract duration as the current offer, and the offer can renew up to the number of times the vendor set on it. For offers that charge based on your usage, the renewed offer might include changes in usage metric pricing if the vendor has updated their public pricing plan. Otherwise, the renewed offer has the same pricing as the current offer. To turn on or turn off auto-renew, see [Manage your accepted offers](https://docs.cloud.google.com/marketplace/docs/manage-accepted-offer). ## After a replacement offer is accepted (For Sellers) A [replacement offer](/gcp-marketplace/create-private-offer/#replacement-offer) does not create a second entitlement. GCP amends the buyer's existing order, and Fours follows: the same entitlement is re-linked onto the accepted replacement offer, so there is still exactly one entitlement for that subscription. Two things change on the entitlement when that happens: - **An "Amendment offer" banner** appears at the top of the entitlement, naming the offer whose information the entitlement is now storing. It is how you tell at a glance that the terms you are reading came from an amendment rather than the original deal. - **The entitlement is renamed** to the new offer's name, so the console and your CRM show the offer that is actually in force rather than the one it replaced. If you reconcile entitlements against offers, expect the entitlement's offer link and name to move when a replacement is accepted — the entitlement record itself is continuous, which is exactly what makes a replacement different from a new offer. --- Source: https://doc.fours.com/gcp-marketplace/cppo/ # CPPO Create and manage GCP Marketplace Channel Partner Private Offers (CPPO) and reseller private offer plans in Fours. --- ## Overview The `Channel Partner Private Offer` (CPPO, called a **Reseller Private Offer Plan** in GCP Marketplace) lets you, as an Independent Software Vendor (ISV/Seller), grant Channel Partners access to wholesale pricing for your software. This delegates the financial and contractual side of the customer relationship in GCP Marketplace to your Channel Partner, while you retain full visibility over the deal. In Fours, you manage the full indirect-channel lifecycle in one place: - `CPPO_OUT` — the Reseller Private Offer Plan you create to authorize a partner (GCP's Marketplace Channel Private Offer). - `CPPO` — the final private offer the Channel Partner creates for the buyer. - `CPPO Entitlement` — the active contract after the buyer accepts. Entitlements support overage usage metering when the relevant usage metering dimensions are available. **Key terms** - **[Marketplace Channel Private Offer (MCPO)](https://cloud.google.com/blog/topics/partners/announcing-google-cloud-marketplace-private-offers)** — a private offer where a Channel Partner works with an ISV to sell a product to a buyer through Google Cloud Marketplace. - **[Reseller Private Offer Plan](https://docs.cloud.google.com/marketplace/docs/partners/resell/reseller-private-offer-plans)** — GCP's term for the configuration an ISV creates to authorize a Channel Partner to resell their product. It defines pricing, terms, and allowed plans. In Fours this is stored as an Offer with type `CPPO_OUT`. - **ISV (Independent Software Vendor)** — the company that owns and publishes the software in GCP Marketplace. - **Channel Partner (Reseller)** — the partner who sells the ISV's product to the buyer and creates the final private offer. **The three-actor lifecycle** A CPPO deal passes through three parties, and each object in Fours belongs to exactly one of them: ```d2 direction: down isv: "You (ISV)" { out: "CPPO_OUT\nReseller Private Offer Plan" approve: "Approve the accepted offer\n(SaaS, unless auto-approval is on)" } reseller: "Channel Partner (Reseller)" { accept_plan: "Accepts the plan\nby the acceptance due date" cppo: "CPPO\nfinal private offer, with the partner's markup" } buyer: "Buyer" { subscribe: "Subscribes in\nGoogle Cloud Marketplace" } entitlement: "CPPO Entitlement in Fours\nyour record of the active contract" isv.out -> reseller.accept_plan: "handed off, status Pending Acceptance" reseller.accept_plan -> reseller.cppo: "partner adds markup and sends it" reseller.cppo -> buyer.subscribe: "offer link" buyer.subscribe -> isv.approve isv.approve -> entitlement: "offer activates" reseller.cppo -> isv.out: "plan becomes Used\n(stays Active if Multi-use)" { style.stroke-dash: 4 } ``` You never see the partner's markup — only your own wholesale plan, the resulting `CPPO` record, and the entitlement. ## Prerequisites Before you can create a Reseller Private Offer Plan, both the ISV and the Channel Partner must complete a few GCP Marketplace and Fours setup requirements. If any are missing, you won't be able to proceed. ### Google Cloud Marketplace - **Register as GCP Marketplace vendors.** Both the ISV and the Channel Partner must be enrolled in Google Cloud Partner Network and have an active Cloud Marketplace vendor account with a verified payment profile in good standing. - **Publish an eligible product (ISV only).** The ISV must have an active, publicly listed product in GCP Marketplace, such as a SaaS application, Kubernetes app, or Virtual Machine product. ### Fours You need **Admin** access to the Fours Console. If you don't have access yet, ask your company admin to invite you to the organization. See [Manage Users and Roles](/get-started/account/). ### GCP IAM roles To let Fours manage your GCP reseller discounts and private offer plans, grant the Fours support user (`gcpdev@suger.io`) the following IAM roles within your **GCP organization** (not your GCP project): - Commerce Business Enablement Configuration Admin - Commerce Business Enablement Reseller Discount Admin - Commerce Producer Admin Or run this command (requires `Organization Administrator` access; find your `ORG_ID` with `gcloud organizations list`): ```bash for ROLE in \ roles/commercebusinessenablement.configAdmin \ roles/commercebusinessenablement.resellerDiscountAdmin \ roles/commerceproducer.admin do gcloud organizations add-iam-policy-binding ORG_ID \ --member="user:gcpdev@suger.io" \ --role="$ROLE" done ``` ## Step 1: Create the Reseller Private Offer Plan After completing the setup, create a Reseller Private Offer Plan (`CPPO_OUT`) in the Fours Console. :::info Reseller Private Offer Plans are stored in Fours as Offers with type `CPPO_OUT`. ::: **Open the Resale Authorization flow** 1. Go to the **Resale** page in the [Fours Console](https://console.suger.io/resale/sent). 2. Click **+ New Resale Authorization** in the upper-right corner. 3. Select the **GCP product** you want to use. This defines what the Channel Partner is allowed to resell. **Add basic information** - **Opportunity Name**: A custom name to identify the resale authorization. It is displayed to the reseller. - **Salesforce Opportunity** (optional): Link the record to a Salesforce Opportunity. - **HubSpot Deal** (optional): Link the record to a HubSpot Deal. - **Salesforce Opportunity / Quote / Account**: When the reseller creates the final private offer from this authorization, the CPPO and its entitlement inherit the Salesforce Opportunity, Quote, and Account you set here — so the resold deal stays linked to the same CRM records without anyone re-entering them. - **Scope**: Required. How the reseller can use the authorization. Pick one: - `Single use`: The reseller can use this plan to create one private offer for one specific customer. - `Multi-use`: The reseller can use this plan to create one or more private offers, to resell your products to one or more of their customers. Leaving it unset, or carrying a value GCP does not accept, blocks the submit with "Please select a valid Scope (Single use or Multi-use)." On an amendment the scope is inherited from the base offer and locked — unless the inherited value is one GCP rejects, in which case the control unlocks so you can correct it. - **Start Time**: When the authorization becomes active. GCP starts a plan at 07:00 UTC on the chosen day, so today is accepted only before 07:00 UTC; from then on the earliest start is tomorrow. Fours checks this again when you submit — which catches a cloned or AI-filled draft still carrying an old date — and names the earliest date you can use: *"Start time must be … or later. GCP starts offers at 07:00 UTC, so today stops being accepted once that hour has passed."* - **End Time**: When the authorization expires. - **Acceptance Due Date**: The last date the reseller can accept the offer. **Today counts** — the date is compared as a UTC calendar date, so a same-day deadline is accepted no matter what time you submit the authorization. It must not fall after the End Time. Besides that End Time rule, it can be no later than today plus three months, minus one day, counted on Google's Pacific calendar — the same **3-month** ceiling Fours applies to a GCP private offer. A later date is refused when you submit, with a message that names the last date you can use. :::info The reseller plan follows these dates When the authorization is created, the underlying reseller plan's own start, end, and acceptance-deadline are derived from the dates above rather than from whatever a cloned draft carried. This is what stops an authorization copied from an older deal from being rejected by GCP for pointing at a window that has already passed. A side effect: while the authorization sits in `Pending Create`, the plan-level and offer-level dates can read as different calendar days, because GCP interprets the plan's dates in its own time zone. They converge once GCP returns the created plan — it is not a sign that something is wrong. ::: - **Billing Account Information**: The customer billing account details. - `Account Name`: The name of the billing account. - `Account ID`: The billing account ID to which the reseller can apply this plan. Enter a Cloud Billing Account ID — three groups of six hexadecimal characters, `XXXXXX-XXXXXX-XXXXXX` — not the reseller's or customer's display name. Anything else is flagged when you leave the field, and blocks the submit, with *"Enter a Cloud Billing Account ID in the format XXXXXX-XXXXXX-XXXXXX."* :::warning - When scope is `Single use`, this is the Cloud Billing subaccount for the resold customer. - When scope is `Multi-use`, this is the Cloud Billing account for the reseller. ::: - **Contact Information**: Your contact info, shared with the reseller. This is **not** visible to the customer. - **Notes to Reseller**: Instructions or context for the Channel Partner. **Set pricing information** Select a **Plan** to define the pricing model. See the [GCP pricing models](/gcp-marketplace/pricing-model/). Fill in the fields that match the selected pricing model. - **Subscription-based plan** - **Monthly flat fee**: How much the reseller pays you for the contract private offer created from this opportunity. - **Reseller discount (off)**: The reseller discount on the commitment amount, from 0% (no discount) to 100% (full discount). :::info For example, if the monthly flat fee is $1000 and the reseller discount is 10%, the reseller pays you $1000 × (1 − 0.1) = $900 every month. ::: - **Usage-based plan** — choose one of the following usage price models: - **Commitment discount with additional usage at list price** - **Monthly commitment**: The monthly commitment fee the reseller pays you. - **Discount on commitment**: The discount on the monthly commitment fee. - **Reseller discount (off)**: The reseller discount on the commitment fee. :::info For example, if the monthly commitment is $1000, discount on commitment is 10%, and reseller discount is 10%, the reseller pays $1000 × (1 − 0.1) × (1 − 0.1) = $810 every month. ::: - **Commitment with all usage discounted** - **Monthly commitment**: The monthly commitment fee the reseller pays you. - **Discount on usage**: The discount on usage fees. - **Reseller discount (off)**: The reseller discount on the commitment fee. :::info For example, if the monthly commitment is $1000 and the reseller discount is 10%, the reseller pays $1000 × (1 − 0.1) = $900 every month. ::: - **Usage-based discount only** - **Discount on usage**: The discount on usage fees. - **Flat fee with usage plan** - **Monthly flat fee**: How much the reseller pays you for the contract private offer created from this opportunity. - **Discount on usage**: The discount on usage fees. - **Reseller discount (off)**: The reseller discount on the commitment fee. :::info For example, if the monthly flat fee is $1000 and the reseller discount is 10%, the reseller pays $1000 × (1 − 0.1) = $900 every month. ::: **Set offer settings (optional)** Enable features resellers can use when creating private offers: - `Allow scheduled start date`: Whether the reseller private offer plan can start on a scheduled date. - `Allow auto renewal`: Whether the reseller private offer plan can auto-renew. - `Number of renewals`: The number of renewals allowed. **Define legal terms** - **End User License Agreement (EULA)**: Choose the Standard GCP Marketplace Contract or your custom contract. - **Reseller Agreement (PDF)** (optional): Select or upload the terms for the Channel Partner. - **Deal Type**: The type of commercial agreement used. Click **Create offer** to finish. It stays greyed out while a required field — marked with an asterisk (*) — is empty or a value isn't valid; hover over it, or press Tab until it has focus, to see what's left. ### Amending an existing CPPO: Change Offer Duration When you build a replacement CPPO, a **Change Offer Duration** switch appears above the date pickers: - **Off** (default) — the new offer coterms to the offer it replaces. **End Time** is locked to the replaced offer's end time, so both finish together. - **On** — set your own **End Time**. Leave it off unless the deal genuinely changes the end date. Coterming is what lets GCP align the new plan's schedule against the replaced offer; without it, GCP has nothing to align to and rejects the publish. If Fours cannot determine which offer the replacement CPPO replaces, the form stops with *"Could not determine the offer being replaced. Reload the entitlement and try again."* The create API refuses the same request, so an amendment is never created as a new reseller plan by mistake. ## Step 2: Hand off to the Channel Partner Once your Reseller Private Offer Plan (`CPPO_OUT`) is active, the Channel Partner creates the final private offer for the buyer. As the ISV you can't build the offer for them, but you initiate the handoff and monitor progress. **Notify the Channel Partner** 1. Open the active Reseller Private Offer Plan in the Fours Console. 2. Click **More actions** in the top-right corner and select **Notify Contact**. 3. Fours emails the reseller a direct link to the plan, letting them know it's ready to use. **Coordinate deal details** Work with your partner to confirm the correct GCP Cloud Billing account based on the plan's Scope. :::info A `Single use` plan requires the customer's Cloud Billing subaccount, while a `Multi-use` plan uses the reseller's Cloud Billing account. ::: ## Step 3: Track buyer acceptance and entitlements After the reseller generates the private offer, you won't see their final markup, but you can oversee the entire deal lifecycle in the Fours Console for full visibility into your indirect channel sales. ### Track your wholesale plan (`CPPO_OUT`) Once the reseller successfully generates the private offer, your original Reseller Private Offer Plan status changes to `Used`. :::info If you set the plan's Scope to `Multi-use`, it remains `Active` so the reseller can use it again. ::: ### Monitor the new private offer (`CPPO`) A new deal entry automatically appears with type `CPPO` and a `Pending Acceptance` status. This confirms the final offer has been delivered to the buyer and is awaiting their approval. ### Confirm buyer acceptance and ISV approval Keep an eye on the `CPPO` record. For GCP SaaS products, you may need to manually approve the accepted offer before it becomes active, unless you have automatic offer approval enabled. ### Manage active entitlements Once the buyer accepts and the offer is activated, a **CPPO Entitlement** is generated automatically. This is your authoritative record of the active contract and fully supports overage usage metering when applicable. ### How resellers and buyers appear in your buyer list Indirect deals introduce two accounts to your buyer list — the reseller and the end customer — and GCP does not always name them consistently. Fours reconciles that for you. **No duplicate row when the reseller got there first.** A reseller who transacts on your behalf often appears in Fours before the marketplace account behind them is known. When that account does show up, Fours attaches it to the row already waiting for it rather than creating a second one — but only if that row has no marketplace account of its own yet. A row already linked to a different account is left alone, because one Cloud Billing account can host several GCP accounts and they are genuinely different buyers. **A resolved name is never replaced by a placeholder.** GCP sometimes omits a billing account's organization display name and nickname. When both are missing, Fours falls back to a label built from the billing account ID — but it will not overwrite a real name it already has with that placeholder. So a reseller you know by name keeps that name even across a sync that returned a thinner payload. If two rows for the same partner do end up in your list, that means they carry different marketplace accounts; contact [support@suger.io](mailto:support@suger.io) rather than merging them yourself. --- Source: https://doc.fours.com/gcp-marketplace/revenue/ # Revenue Track billed revenue, marketplace fees, and payouts from your GCP Marketplace orders in Fours. --- ## Overview Google handles billing on its side — it charges your customers, deducts its marketplace fee, and disburses your earnings. Fours does **not** process GCP payments. Instead, Fours **ingests** the billing reports Google delivers to your Cloud Storage report bucket and normalizes them into unified **revenue records**, so GCP revenue sits alongside your AWS, Azure, and Snowflake revenue in one place. Fours syncs several GCP reports: | Report | What it contains | |--------|------------------| | **Charges and Usage** | The primary billing source — the amount charged to the customer and the amount due to you (the seller). | | **Disbursements / Detailed Disbursements** | The confirmed payout amounts Google sent you, including the marketplace fee. This is the **only** source of a GCP record's disbursed amount. | | **Insights** | Customer and company metadata used to enrich buyer records. | Fours resolves each charge to the matching Fours buyer, product, and entitlement where possible. ## Where to find GCP revenue GCP is a first-class channel in Fours' revenue surfaces: 1. Open **Revenue → Revenue Records**. 2. Set the **Channel** filter to **GCP**. Two tabs are available: - **Joined Records** — one normalized row per order, with billed amount, marketplace fee, collectable amount, and disbursement. - **Raw Records** — the source charge-and-usage rows exactly as Google reported them. You can also see GCP revenue for a single **buyer** on its detail page, for a single **entitlement** on its detail view, or for a **product**. See the [Revenue Records](/revenue/revenue-records/) documentation for the full page reference. ## What each amount means Fours maps the raw GCP report data into the normalized record as follows: | Revenue record field | GCP source | Meaning | |----------------------|------------|---------| | **Billed (Invoice amount)** | Charges | What Google billed the customer. | | **Collectable** | Due to partner/seller | What you receive after Google's marketplace fee. | | **Partner fee** | Charges − collectable (net of prepay credits) | Google's marketplace fee. | | **Disburse amount** | Detailed Disbursements payout | Money Google actually paid out to you. Zero until the Detailed Disbursements report arrives. | | **Expected payout (due date)** | Derived from the charge month | The **21st of the month after** the charge month, in UTC. Fours computes this itself; Google does not report it. | | **Disburse date** | — | **Not populated for GCP.** Google does not report the date a payout actually left its side, so this field stays empty on GCP records. | ## How a GCP refund appears **A refund does not create its own revenue record.** Google reports refunds as rows in the same charge-and-usage report as the charges, and Fours turns each one into a **credit memo** linked to the original monthly revenue record it refunds. The refunded amounts are then projected onto that original record, where they show up in the **Refund Invoice Date**, **Refund Invoice Amount**, **Refund Disburse Date** and **Refund Disburse Amount** columns. Two consequences worth knowing: - **There is no duplicate negative row.** The refund is visible on the record it belongs to, so a month's revenue reads as one line with its refund attached, rather than a positive line and a negative line you have to pair up yourself. - **The memo carries Google's own reason text**, verbatim, when the report supplies one. A whole report month is reconciled together. If Google republishes a month's report with rows in a different order, Fours rebuilds that month's memos as a set rather than patching them one at a time — otherwise a re-ordered report would leave the earlier memos in place and the projection would count the refund twice. ## Why a GCP record has no disburse date Google reports the charge month and, later, the payout amount — but never the date on which it paid you. A GCP revenue record is therefore created with **no disburse date and a disbursed amount of zero**, and Fours fills in the money afterwards from the Detailed Disbursements report. To keep the record on a timeline anyway, Fours derives an **expected payout date** — the 21st of the month following the charge month, in UTC — and stores it as the record's **payment due date**. That expected date, not a disburse date, is what drives the record's payment status: ```d2 direction: down charge: "Charge month\nGoogle bills the customer\n(Charges and Usage report)" create: "Fours creates the revenue record\nInvoice date = charge date\nDisburse date = (none)\nDisbursed amount = 0" expected: "Expected payout\n21st of the NEXT month, UTC\nstored as the payment due date" before: "Before the expected date" { shape: diamond } after: "On or after the expected date" { shape: diamond } pending: "PENDING" confirmed: "Detailed Disbursements report\nreports a confirmed amount\n(the only source of a real payout figure)" amount: "Confirmed amount\nis non-zero?" { shape: diamond } paid: "PAID\nincludes negative clawback\nand refund months" overdue: "OVERDUE\nnothing confirmed yet" charge -> create create -> expected: "derived, not reported" expected -> before expected -> after before -> pending after -> amount confirmed -> amount: "supplies the amount" amount -> paid: "yes (positive or negative)" amount -> overdue: "no — still zero" ``` Read the states as follows: | Payment status | When a GCP record is in it | |----------------|-----------------------------| | **PENDING** | The expected payout date has not arrived yet. | | **PAID** | The expected payout date has passed **and** the Detailed Disbursements report has apportioned a **non-zero** amount to the record. A refund or clawback month carries a *negative* amount, and that also settles the line — otherwise a credit would sit in aging as overdue forever. | | **OVERDUE** | The expected payout date has passed and the confirmed amount is still zero. | :::caution **Do not read the Detailed Disbursements report date as a payout date.** The date on the report is the time Google generated the report, not the time money moved. Fours deliberately does not turn it into a disburse date, which is why GCP records cannot contribute to any metric that measures the gap between invoicing and payout — for example **Avg days to payout** on [Channel Performance](/revenue/revenue-analytics-and-reports/). ::: Two places in the product show this explicitly: on [Invoices](/revenue/invoices/), a GCP invoice's subline reads **Expected payout <date>** where other channels read *Due* or *Overdue*; and in [reports](/revenue/revenue-analytics-and-reports/), a GCP row with no disburse date is flagged **Is Estimated**. :::info **Prepay credits** are specific to GCP and reduce the fee base rather than counting as revenue. GCP reports usage rather than formal invoices, so Fours assigns a consistent invoice identifier per charge date, SKU, and account. GCP's reports do not include a separate tax line, so the tax field is not populated for GCP records. ::: :::info Orders sold through a **reseller** (a parent billing account) are tagged as **Resold** with the reseller's details; direct orders are tagged **Direct**. ::: ## Sync Revenue sync runs automatically once your GCP Marketplace integration is connected. Fours reads new report files as Google delivers them and updates the corresponding revenue records. - The **first** sync performs a historical backfill; subsequent syncs re-scan a trailing window so late-arriving charges and disbursements are picked up. - To rebuild that history later, run a [full sync](/gcp-marketplace/integration/#run-a-full-sync) on the integration. It re-reads the Insights, Charges and Usage, Disbursements and Detailed Disbursements reports from the integration's **Report Start Date** — or the year before the run, when none is set — and rebuilds the revenue records up to two days before the run started. It needs the integration's **GCP Project Number**, and it skips the revenue records while **Revenue Record Sync Disabled** is on. - Until the Detailed Disbursements report arrives, a record's disbursed amount stays **zero** and it sits at its expected payout date. Once the report lands, Fours apportions the real per-line payout across the records for that entitlement and charge month, by each record's share of the collectable amount, so the parts add up to the payout exactly. No disburse **date** is ever filled in — see [Why a GCP record has no disburse date](#why-a-gcp-record-has-no-disburse-date). - Because the Detailed Disbursements report is the only source of a confirmed payout, a sync that cannot read it is aborted rather than completed. Completing it would zero out every previously confirmed amount and flip those records to overdue. :::caution GCP revenue data reflects what Google reports in your report bucket. If an order or payout is missing, confirm the corresponding report has been delivered — Fours can only surface what Google has published. ::: ## FAQ ### Why is my collectable amount lower than the billed amount? The collectable amount is the charged amount minus Google's marketplace fee. Fours derives the fee from the difference between what Google billed the customer and what is due to you (after prepay credits), so it reflects the exact rate Google applied. ### Why don't GCP records show tax? Google's marketplace reports do not break out a separate tax line, so Fours leaves the tax field empty for GCP records. ### When will I see the final disbursement? The confirmed payout amount appears once Google delivers the Detailed Disbursements report and Fours' next sync ingests it. Before that, the record's disbursed amount is zero and it carries only its **expected** payout date — the 21st of the month after the charge month. ### Why is the disburse date empty on my GCP records? Because Google never reports it. Google tells you the charge month and, later, the payout amount, but not the day the money moved. Fours leaves the disburse date empty rather than substituting the report's generation date, and tracks the record against its expected payout date instead. See [Why a GCP record has no disburse date](#why-a-gcp-record-has-no-disburse-date). --- Source: https://doc.fours.com/gcp-marketplace/signed-buyer-handoff/ # Signed Buyer Handoff Verify that a buyer arriving at your signup page was really just sent there by Fours. --- ## The problem this solves When a buyer purchases your product on Google Cloud Marketplace, Fours creates the entitlement and redirects the buyer to your signup URL with the entitlement ID in the query string. Your page reads that ID and binds the new account to the purchase. By default that ID is the only thing your page has to go on — and it is not a secret. It appears in browser history, support tickets, forwarded confirmation emails and webhook logs. Anyone who obtains one can open your signup page with it and bind *their* account to *someone else's* purchase. Turning on **Signed Buyer Handoff** changes the redirect so it also carries a short-lived token that only Fours can produce. Your page verifies it before trusting anything, and "knows the entitlement ID" stops being the same thing as "is the buyer". :::info This is opt-in per integration and off by default. Ship your verification code first, then flip the toggle — if you enable it before your page can read a token, your signup page will reject every buyer. ::: ## Turning it on Go to **Integrations → GCP → Edit** and enable **Signed Buyer Handoff**. ## What changes in the URL **Before (default):** ``` https://app.yourcompany.com/gcp-signup ?sugerEntitlementId=ent_EXAMPLE1 &partner=gcp &gcpAccountId=016AAA-111111-222222 &offerType=PRIVATE ``` **After:** ``` https://app.yourcompany.com/gcp-signup ?token=eyJhbGciOiJSUzI1NiIsImtpZCI6… &partner=gcp ``` Every field that used to be a query parameter is now a signed claim inside the token. Read them from the verified payload — never by decoding the token without verifying it. ## What's inside the token | Claim | Example | Meaning | |---|---|---| | `iss` | `https://apiv2.suger.cloud` | Issuer. Verify this. | | `aud` | `app.yourcompany.com` | Audience. Must equal your own domain. Verify this. | | `exp` | `1727136300` | Expires 5 minutes after issue. Verify this. | | `jti` | `9f1c…` | Unique token ID (UUID). Useful for your own logging. | | `ent` | `ent_EXAMPLE1` | Fours entitlement ID. | | `buyer` | `buyer_EXAMPLE1` | Fours buyer ID. | | `product` | `prod_EXAMPLE1` | Fours product ID. | | `org` | `org_EXAMPLE1` | Fours organization ID. | | `gcp_account` | `016AAA-111111-222222` | GCP billing account. | | `partner` | `gcp` | Marketplace. | | `offer_type` | `PRIVATE` | Offer type. | ### About `aud` The audience is the **host Fours actually redirects the buyer to**. Normally that is the host of your product's Fulfillment URL. If you use a `BeforeSignupRedirect` hook to send buyers somewhere else, the audience follows the hook — so it always matches the page receiving the request. ## How to verify Fetch Fours' public keys once at startup and cache them: ``` https://apiv2.suger.cloud/public/handoff/jwks.json ``` :::caution This is a dedicated JWKS for handoff tokens. It is **not** the same as the OAuth JWKS at `/.well-known/jwks.json`, which publishes different keys and will not verify these tokens. ::: Then on every handoff, check three things: 1. **Signature** — proves Fours issued the token. 2. **`exp`** — proves it is less than 5 minutes old. 3. **`aud`** — proves it was minted for **your** domain, not another seller's. If all three pass, every claim is trustworthy. Allow about 30 seconds of clock skew on `exp`. ### Node (`jose`) ```js import { jwtVerify, createRemoteJWKSet } from "jose"; const JWKS = createRemoteJWKSet( new URL("https://apiv2.suger.cloud/public/handoff/jwks.json") ); export async function verifyHandoffToken(token) { const { payload } = await jwtVerify(token, JWKS, { issuer: "https://apiv2.suger.cloud", audience: "app.yourcompany.com", clockTolerance: "30s", }); return payload; // payload.ent, payload.buyer, payload.product, … } ``` ### Go (`jwx`) ```go import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jwt" ) const jwksURL = "https://apiv2.suger.cloud/public/handoff/jwks.json" jwksCache, _ := jwk.NewCache(ctx) _ = jwksCache.Register(jwksURL) func verifyHandoff(ctx context.Context, token string) (jwt.Token, error) { keyset, err := jwksCache.Get(ctx, jwksURL) if err != nil { return nil, err } return jwt.Parse([]byte(token), jwt.WithKeySet(keyset), jwt.WithIssuer("https://apiv2.suger.cloud"), jwt.WithAudience("app.yourcompany.com"), jwt.WithAcceptableSkew(30*time.Second), ) } ``` ### Python (`PyJWT`) ```python import jwt from jwt import PyJWKClient jwks_client = PyJWKClient("https://apiv2.suger.cloud/public/handoff/jwks.json") def verify_handoff(token: str) -> dict: signing_key = jwks_client.get_signing_key_from_jwt(token).key return jwt.decode( token, signing_key, algorithms=["RS256"], issuer="https://apiv2.suger.cloud", audience="app.yourcompany.com", leeway=30, # seconds of clock skew ) ``` ## Server-side verification (optional) If implementing JWT verification is awkward in your stack — Salesforce Apex, for instance — you can POST the token to Fours instead and get the decoded claims back only if the signature, expiry and audience all check out. ``` POST https://apiv2.suger.cloud/public/handoff/introspect Content-Type: application/json { "token": "eyJ…", "audience": "app.yourcompany.com" } ``` `audience` is **required**, and must be your own domain. Fours checks the token against it for you, so this endpoint gives you the same guarantee as verifying offline. Without it we could only tell you a token is validly signed — not that it was meant for *you*, which is the part that stops another seller's token being replayed against your signup page. Response (`200`): ```json { "ent": "ent_EXAMPLE1", "buyer": "buyer_EXAMPLE1", "product": "prod_EXAMPLE1", "org": "org_EXAMPLE1", "partner": "gcp", "offer_type": "PRIVATE", "gcp_account": "016AAA-111111-222222", "jti": "9f1c…", "exp": "2026-10-02T15:04:05Z" } ``` Other responses: `400` (missing `token` or `audience`), `401` (invalid signature, expired, or wrong audience). Offline verification is still the recommended path — it is a few lines in any language and costs you no network round-trip on your signup page. ## Worked example A buyer purchases your product. Fours verifies Google's signed token, creates the entitlement, and redirects: ``` https://app.yourcompany.com/gcp-signup?token=eyJhbGciOiJSUzI1NiIsImtpZCI6…&partner=gcp ``` Your handler: ```js app.get("/gcp-signup", async (req, res) => { let payload; try { payload = await verifyHandoffToken(req.query.token); } catch (err) { // Invalid signature, expired, wrong audience, or tampered. return res.status(400).send("This signup link is invalid or has expired."); } // payload.ent is now trusted. const entitlement = await sugerClient.getEntitlement(payload.org, payload.ent); renderSignup({ entitlement }); }); ``` ## Good to know **Tokens last 5 minutes.** That is long enough for a redirect and short enough that a URL recovered from browser history the next morning is useless. Verify on first load and establish your own session; do not ask the buyer to re-use the link. **Tokens are not single-use.** Within those 5 minutes the same token verifies more than once. If your flow needs strict single-use, dedupe on the `jti` you receive. **The token proves identity, nothing more.** It is not a bearer credential for the Fours API and cannot be used to call us on the buyer's behalf. **Existing integrations are unaffected.** Until you enable the toggle, your signup URL keeps receiving the same plain query parameters it always has. ## Troubleshooting | Symptom | Cause | Fix | |---|---|---| | `JWTExpired` | More than 5 minutes between redirect and verification, or server clock drift | Allow 30s clock tolerance; check NTP sync. | | `JWTClaimValidationFailed: aud` | The audience in the token is not the string you passed | Match the host Fours redirects to. If you use a `BeforeSignupRedirect` hook, that is the hook's host, not your Fulfillment URL's. | | `JWSSignatureVerificationFailed` | Wrong JWKS, tampered token, or a stale cache after key rotation | Confirm you are using `/public/handoff/jwks.json` and not `/.well-known/jwks.json`. Then refresh the cache. | | No `token` parameter arrives | The toggle is off, or this redirect fell back to plain parameters | Check the toggle. Fours falls back to unsigned parameters rather than failing a purchase, so handle both while you migrate. | | `400` on introspect | Body is missing `token` or `audience` | Both fields are required. | | `401` on introspect | Signature invalid, expired, or wrong audience | Same debugging path as the offline errors above. | ## Testing against dev Everything above works in the dev environment with the hostname swapped: ``` https://apiv2.dev.suger.cloud/public/handoff/jwks.json https://apiv2.dev.suger.cloud/public/handoff/introspect ``` Tokens issued there carry `iss: https://apiv2.dev.suger.cloud`, so point your verifier at the matching issuer when testing. --- Source: https://doc.fours.com/gcp-marketplace/ # Google Cloud Marketplace Google Cloud Marketplace has the longest run-up of the marketplaces Fours supports. Before you can list anything, your organization has to join Google Cloud Partner Network and be approved as a Marketplace vendor, which includes Google validating your solution architecture. Budget about four weeks for a net-new listing, three of which are Google's review; migrating an existing listing takes about five days. Google also approves listings in **phases** — each phase must clear before the next opens, and editing something after submission restarts the review for that phase. Fours connects to your Producer Portal project using Workload Identity Federation, so no long-lived service account keys change hands. Once connected, Fours manages listings, private offers, entitlements, and usage metering. A few steps still have to be done in the Producer Portal itself, because Google does not expose an API for them — the listing guide calls out exactly which ones. ## The path to your first Google Cloud sale 1. **[Self-Serve Onboarding Guide](/gcp-marketplace/self-serve-onboarding/)** — the phased plan, including the Partner Network and solution-validation work that has to happen before Fours enters the picture. 2. **[Integration](/gcp-marketplace/integration/)** — prepare your GCP project, create the service account Fours impersonates, and complete the Workload Identity Federation handshake. 3. **[Pricing Model](/gcp-marketplace/pricing-model/)** — free, subscription, usage-based, and combined; unlike AWS and Azure, one Google Cloud listing can carry more than one of them. 4. **[List & Update Product](/gcp-marketplace/list-product/)** — one guide for both publishing a listing and changing it later, with the phase-by-phase approval sequence and the steps that must happen in Producer Portal. 5. **[Create Private Offer](/gcp-marketplace/create-private-offer/)** — combine a product plan, custom offer pricing, a prepay or postpay schedule, and a contract duration into one negotiated deal. 6. **[Revenue](/gcp-marketplace/revenue/)** — read the charges, disbursement, and insights reports Google drops into your Cloud Storage bucket as normalized revenue records. ## Hand the deal to a buyer or a reseller - **[Accept Private Offer](/gcp-marketplace/accept-private-offer/)** — what the buyer does with the offer link, and the Cloud Billing and procurement IAM roles they need before they can accept. - **[CPPO](/gcp-marketplace/cppo/)** — authorize a channel partner at wholesale pricing through a Reseller Private Offer Plan, then follow the partner's offer and the resulting entitlement in Fours. ## Scope and limits :::info This section covers SaaS products on Google Cloud Marketplace. Private offers can also target Kubernetes apps and VM images, but the listing guidance here is written for integrated SaaS. Google reports by file rather than by API: it charges your customers, takes its marketplace fee, disburses your earnings, and drops the charges, disbursement, and insights reports into the Cloud Storage bucket you configure during integration — which is where Fours reads them from. No payment passes through Fours. ::: --- Source: https://doc.fours.com/snowflake-marketplace/integration/ # Integration Grant Fours the necessary access to manage your Snowflake Marketplace on your behalf, no more no less. --- ## Overview To sell on Snowflake marketplace, you first need to be a Snowflake Marketplace provider. There are several requirements to meet before you can list products/services on Snowflake Marketplace. Snowflake lists them under [requirements to become a provider](https://docs.snowflake.com/en/collaboration/provider-becoming#requirements-to-become-a-provider). Once you are a Snowflake Marketplace provider, you can list your products on Snowflake Marketplace and integrate with Fours to manage your marketplace offerings. ## Become A Snowflake Marketplace Provider - You must use a full Snowflake account. Trial accounts can share data with specified consumers, but not on the Snowflake Marketplace. - You must not be using a Reader Account. - You must have the ACCOUNTADMIN role or be assigned a role with provider privileges. See [Privileges required for working with listings](https://docs.snowflake.com/en/collaboration/provider-becoming#privileges-required-for-working-with-listings). - You must meet the [Legal requirements for providers and consumers of listings](https://docs.snowflake.com/en/collaboration/collaboration-listings-legal). See [Review and accept the Snowflake Provider and Consumer Terms](https://docs.snowflake.com/en/collaboration/provider-becoming#label-accept-provider-tos-marketplace). - If your account is in a U.S. government region, you must also accept the cross-region disclaimer. Snowflake covers it under [requirements to become a provider](https://docs.snowflake.com/en/collaboration/provider-becoming#requirements-to-become-a-provider). ## Integration Prerequisite Fours relies on key-pair authentication to get access to your Snowflake account. Follow the steps below to prepare resources required for Fours integration. 1. **Configure Key Pair Authentication**. Follow the [official guideline](https://docs.snowflake.com/en/user-guide/key-pair-auth#configuring-key-pair-authentication) to create a key pair. You can generate an **encrypted** key pair or **unencrypted** key pair. 2. Click the `Connect` button of Snowflake Marketplace integration on the [Integrations page](https://docs.snowflake.com/en/user-guide/key-pair-auth#configuring-key-pair-authentication) in Fours console. 3. Input the `Account`, `User` and `Private Key` of your Snowflake account. > ![Snowflake account connection form with Account, User, and Private Key fields](images/snowflake-marketplace-integration.jpg) 4. Click the `Connect` button to complete the integration. ## Give the role its listing privileges The user you connect acts under a Snowflake role, and the sync reads each listing with `DESCRIBE LISTING`, `SHOW PRICING PLANS IN LISTING` and `SHOW OFFERS IN LISTING`. If that role is not granted the privileges those commands need, Snowflake refuses them per listing with an *insufficient privileges* error. The sync does not fail when that happens — it carries on and imports what it can. The cost is silent and per listing: - The listing still appears in Fours, but **without the detail those commands provide**. - Its **product type** is inferred from the share type rather than read from the listing, so it can be less specific than it should be. - Its **pricing plans** may be missing. - Its **private offers** are not imported or updated. Listing a listing's offers takes `MODIFY` (or `OWNERSHIP`) on that listing, not just `USAGE`. Without it, Fours skips that listing's offers and carries on with your other listings and the rest of the sync, including revenue. Snowflake's error message suggests `MANAGE GRANTS`, but the grant that fixes it is `MODIFY` on the listing. Nothing in the console announces this, so if a Snowflake listing shows up with a surprising product type, no pricing plans or none of its private offers, check the connected role's privileges first. Use `ACCOUNTADMIN`, or a role granted the [privileges required for working with listings](https://docs.snowflake.com/en/collaboration/provider-becoming#privileges-required-for-working-with-listings), then re-sync. ## Edit Integration Editing an existing Snowflake Marketplace integration is not supported. The practical way is to delete it and then re-connect it with new inputs. ## Delete Integration The Snowflake Marketplace integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the **Private Key** will be deleted immediately & permanently from Fours. No time window or methods to recover. --- Source: https://doc.fours.com/snowflake-marketplace/provider_profile/ # Provider Profile Before listing your product on Snowflake Marketplace, you need to set up your provider profile. ## Overview A provider profile represents your company on the Snowflake Marketplace. It contains essential information about your organization and is required before you can list any data products or applications. ## Provider Profile Fields | Field Name | Description | Example | |------------|-------------|----------| | Company Icon | A high-resolution logo (JPG/PNG, max 2MB, 256x256px recommended) | image.jpg | | Company Name | Your company's display name (not Snowflake account name) | Example Company | | Company Description | 2-3 sentence company introduction | Example Company, recognized as the leading source of weather forecasts... | | Consumer Contact Email | Email for data access requests (24-hour response expected) | sales@example.com | | Support Link or Email | Technical support contact information | support@example.com | | Privacy Policy Link | URL to company privacy policy (must be publicly accessible) | https://www.example.com/privacy | | Business Contact Email | Email for Snowflake's listing-related communications | admin@example.com | | Technical Contact Email | Email for Snowflake's data-sharing communications | operations@example.com | ## Managing Your Profile ### Creating/Editing a Profile 1. Sign in to Snowsight 2. Switch to ACCOUNTADMIN role or a role with CREATE DATA EXCHANGE LISTING privilege 3. Navigate to Data Products » Provider Studio » Profiles 4. Select Update Profile (or create new) 5. Fill in required information 6. Submit for approval **Note:** Most profile changes require Snowflake approval before becoming visible in the Marketplace, except for Business and Technical contact updates. ### Deleting a Profile You can delete a provider profile if it's not associated with any listings: 1. Sign in to Snowsight 2. Switch to ACCOUNTADMIN role or appropriate privileged role 3. Navigate to Data Products » Provider Studio » Profiles 4. Select the profile 5. Choose Delete Profile 6. Confirm deletion **Important:** Ensure no listings are associated with the profile before attempting deletion. --- Source: https://doc.fours.com/snowflake-marketplace/pricing_plans/ # Pricing Plan Snowflake Marketplace Product Pricing Plans --- ## Overview Snowflake Marketplace offers two primary pricing models: **Usage-Based** and **Subscription-Based**. You can implement one or both models for your product listing. ## Usage-Based Pricing Usage-based pricing charges consumers monthly based on their actual consumption of your data product. This model offers several charging options: ### 1. Billable Events > Note: Custom Event Billing is only available for application listings. Custom Event Billing allows you to charge for specific application usage patterns, such as: - Per row modified - Per procedure call - Per row accessed - Per unique row updated monthly (monthly active rows) - Custom-defined events in your application ### 2. Per-Query Charges - Fixed price per query accessing paid data - Applies in addition to any monthly fees (if applicable) ### 3. Monthly Fee - Fixed calendar month fee - Triggered by: - First query execution against a Snowflake Native App - First access to paid listing data share - First run of a Snowflake Native App with Snowpark Container Services - Not prorated; full month charged regardless of activation date - No charge if no usage occurs during the month ### Usage-Based Pricing Requirements For plans with dynamic charges (per-query or Custom Event Billing), you must specify: 1. **Maximum Monthly Charge Cap** - Defines the upper limit for total monthly costs - Includes all usage-based charges - Usage becomes free once cap is reached 2. **Free Query Allowance** - First query always incurs charges - Specify number of free queries after the first query - Regular pricing resumes after free queries are used ## Subscription-Based Pricing Subscription-based pricing requires upfront payment for a specified term. Two billing options are available: 1. **Recurring Billing** - Automatic renewal at term end - Continuous access to data product 2. **Non-Recurring Billing** - Fixed-term access - Manual renewal required ### Installment Plan Options To provide payment flexibility, you can offer installment plans that: - Split total cost into multiple payments - Allow customized payment schedules - Variable payment amounts - Front-loaded or back-loaded payments - Optional zero-payment periods ## How the committed amount is derived When a private offer is accepted, Fours records a committed amount on the resulting entitlement and uses it in your notifications. Where that number comes from depends on the offer's payment type: | Payment option on the offer | Committed amount | | --- | --- | | **Require full payment upfront** | The offer's **contract value** | | **Accept installments** | The offer's **contract value** | | Everything else (for example, follow the billing frequency) | The pricing plan's base fee, after the offer's discount | For an upfront or installment offer the contract value is what the buyer actually committed to. It is negotiated per deal and often bears no relation to the plan's per-cycle base fee — an installment schedule, for instance, sums to the contract value rather than to any multiple of the base fee. Deriving the commit from the base fee in those cases produced a wrong figure on the entitlement, so the contract value wins whenever it is present and greater than zero. If a Snowflake entitlement's commit looks wrong, check the offer's contract value first — that is the number it is reading. --- Source: https://doc.fours.com/snowflake-marketplace/list_product/ # List Product List your product on Snowflake Marketplace. --- ## Prerequisites Before creating a listing, ensure you have: 1. Accepted the Snowflake Provider and Consumer Terms 2. Reviewed the Provider Policies 3. Created a provider profile (required for paid listings) 4. Set up your account for paid listings (if applicable) 5. Access to a role with provider privileges 6. Prepared your data for listing — Snowflake's [guide to using listings as a provider](https://docs.snowflake.com/en/collaboration/provider-becoming) covers the requirements ## Types of Listings ### 1. Private Listings Share data or apps directly with specific consumers: - **Free Private Listings**: Share data at no cost with selected accounts - **Paid Private Listings**: Monetize data sharing with specific accounts ### 2. Public Marketplace Listings Make your data product available to all Snowflake Marketplace users: - **Free**: Available at no cost - **Paid**: Monetized offerings - **Trial**: Limited access versions of paid products ## Creating a Listing 1. Navigate to **Data Products » Provider Studio** in Snowsight 2. Select **+ Create Listing** 3. Choose visibility: - **Specified consumers** for private listings - **Snowflake Marketplace** for public listings 4. Add **Data Products** for the listing 5. Set **Access Type** to paid. 6. Create **Pricing Plans** for the listing 7. Configure the listing details: - Add title and subtitle - Write description - Add legal terms and conditions - Configure trial settings (if applicable) ## Publishing Process ### For Private Listings 1. Complete the listing configuration 2. Click **Publish** 3. Share access information with your consumers ### For Marketplace Listings 1. Complete the listing configuration 2. Submit for Snowflake approval 3. Wait for review feedback 4. If approved, click **Publish** 5. If rejected, address feedback and resubmit ## Important Notes - Contact Snowflake's business development team before creating paid marketplace listings - Published listings are visible in all Marketplace regions - Auto-fulfillment settings are required for sharing with consumers in different regions - Monitor usage through Provider Studio analytics --- Source: https://doc.fours.com/snowflake-marketplace/create-private-offer/ # Create Private Offer Create a private offer to share your data product or application with specific consumers on Snowflake Marketplace. There are two ways to price a private offer: - **Based on a pricing plan** — reuse one of your published pricing plans, applying a discount and contract terms on top of it. - **One-time pricing** — charge a single flat contract value instead of an ongoing pricing plan. Both follow the same flow below; the only difference is what you select for **Pricing Plan** in step 2. ## Create a Private Offer ### 1. Set Offer Details 1. Click create private offer in **Offer page**. 2. Select your listing. 3. In **Target Customer**, enter the buyer's data sharing account identifier, in the format `org_name.account_name` - This is the unique identifier for your customer's Snowflake account 4. Enter **Offer name** - A descriptive name that helps identify this specific offer 5. Set **Expiration Date** - The date after which this offer can no longer be accepted by the buyer. It must be a future date: the form refuses today's date with *Expiration date must be in the future*. ![Create Private Offer Step 1](images/snowflake-create-offer-step1.jpg) ### 2. Configure Billing and Payments Select a **Pricing Plan**. The dropdown lists your published pricing plans plus a **One Time Offer** option. Your choice here determines how the offer is priced. #### Option A — Based on a pricing plan 1. Select one of your existing **published pricing plans**. 2. Set **Contract Duration** - Specify how long the agreement will remain active. 3. Set **Discount** percentage off the public price - Enter a percentage reduction from your published pricing. 4. Configure payment settings based on the pricing type: **For Subscription-Based Pricing:** - Choose **Payment option**: - **Require full payment upfront** - Customer pays the entire committed amount immediately. - **Follow the billing frequency** - Customer is billed each billing cycle of the plan. - **Accept installments** (equal or custom amounts) - Allows customers to spread payments over time. - Choose **Date of first invoice** (when offer accepted or a specific date) - Determines when billing begins. #### Option B — One-time pricing offer Choose this when you want to charge a single flat amount rather than an ongoing pricing plan. 1. Select **One Time Offer** from the **Pricing Plan** dropdown. 2. Choose a **Contract Type** - **Limited-time** or **Recurring (Subscription)**. 3. Enter the **Contract Value** - The total one-time amount to charge, in USD. 4. Set **Contract Duration** - The length of access the buyer receives for the one-time charge. 5. Set **Discount** percentage (optional) - A reduction applied to the contract value. 6. Choose **Payment option**: - **Require full payment upfront** - Customer pays the full contract value immediately. - **Accept installments** - Split the contract value into multiple payments. When selected, choose an **Installment frequency** (Monthly, Quarterly, or Yearly) and optionally set custom amounts per installment. 7. Choose **Net payment terms** (optional) - Due on receipt, Net 30, Net 60, or Net 90 days. 8. Choose **Date of first invoice** (when offer accepted or a specific date). :::note **Installment frequency** and **Net payment terms** are not exclusive to one-time offers — the same controls are available for pricing-plan (subscription) offers when you choose **Accept installments**. ::: :::info Snowflake Marketplace private offers are billed in **USD** only. ::: #### Subscription offer example ![Create Private Offer Step 2 - Subscription](images/snowflake-create-offer-step2-subscription.jpg) #### Pay-as-you-go offer example ![Create Private Offer Step 2 - Pay As You Go](images/snowflake-create-offer-step2-payg.jpg) ### 3. Set Access and Terms 1. Select **Access start date**: - When offer accepted - Access begins immediately after customer accepts - On specific date - Access begins on a predetermined future date 2. Choose **Terms of service**: - Use default terms - Apply standard Snowflake Marketplace terms - Use custom terms - Upload your own terms of service document - Provide terms offline - Indicate that terms are handled outside the marketplace 3. (Optional) Add **Attachments** — PDF files the buyer can download while viewing the offer. Click **Attach file** for each one, up to **5 PDFs of at most 5 MB each**; the trash icon removes a row. - Only real PDF files are accepted — renaming another file type to `.pdf` does not get it through. - Fours normalizes each file name for Snowflake: any run of characters other than letters, digits, dots, underscores and hyphens becomes a single underscore, and a `.PDF` extension becomes `.pdf` — so `Terms Supplement.PDF` is attached as `Terms_Supplement.pdf`. Two attachments whose normalized names match are rejected. - The attached files are listed under **Attachments** on the offer's detail page. ### 4. Review and Submit Fields marked with an asterisk (*) are required, and which ones depends on your choices — a one-time offer, for example, also needs **Contract Type** and **Contract Value**. **Create offer** stays greyed out while a required field is empty or a value isn't valid. To see what's left, hover over the button, or press Tab until it has focus: its tooltip, headed *Please complete:*, lists each step that still needs work and the fields in it — for example, *Step 2 Pricing information — Contract Type* — with the reason beside any value that isn't valid. A value that isn't valid is also outlined in red, with the reason beneath the field. Review all details and click **Create offer**. Once submitted, the offer will be sent to the specified customer account for review and acceptance. After successfully creating a private offer, you can copy the offer URL and share it with the buyer. ## Notify the Buyer Open the offer and click **Notify** on its **Contacts** card to email the buyer. This sends **two** emails: 1. **Fours' notification**, with a link to the offer. 2. **Snowflake's own offer notification**, sent by Snowflake to the same recipients. Both are sent on purpose. Some buyers' email security gateways strip hyperlinks out of mail sent by third parties, which leaves Fours' **Private Offer** button unusable — Snowflake's own email reaches those buyers. If your buyer reports an email with a dead or missing link, ask them to look for the Snowflake-sent one. **Recipients** are the offer's contacts that have an email address, with duplicates removed. Selecting specific contacts notifies only those; notifying without selecting anyone emails every contact on the offer. :::info When the Snowflake email is skipped Snowflake's email is skipped quietly in two cases: the offer has not been created in Snowflake yet, and no contact on the offer has an email address. If the Snowflake side fails for any other reason — an expired credential, an outage — Fours' own notification is still sent, so the buyer always hears from you. ::: ## If the offer is rejected Snowflake validates a private offer against an *offer manifest*, and when a field is wrong it answers with a driver error naming the manifest field. Fours translates the ones Snowflake documents into a plain sentence on the offer, so you read what to fix rather than which manifest key failed. Each message names the field in product terms and restates the rule: | Field Snowflake rejected | What Fours tells you it must be | | --- | --- | | Customer Snowflake account | An existing Snowflake account, written as `organization_name.account_name`. | | Contract type | `SUBSCRIPTION` or `LIMITED_TIME`. | | Contract duration | The length of the contract in months. | | Offer start date preference | `SPECIFIC_DATE` or `OFFER_ACCEPTED_DATE`. | | Invoice start date preference | `OFFER_ACCEPTED_DATE`, `SPECIFIC_DATE`, `FIRST_DAY_NEXT_MONTH`, or `TWO_DAYS_AFTER_OFFER_ACCEPTED_DATE`. | | Invoice start time / invoice end time | A valid date and time. | | Access start time / access end time | A valid date and time. | | Offer expiration time | A valid date and time. | | Discount | A number. | | Payment type / payment method | `INVOICE` or `CREDIT_CARD`. | | Pricing plan name | A pricing plan that exists on the listing. | | Terms of service setting | Type `CUSTOM`, `DEFAULT`, or `OFFLINE`. | | Default offer setting | `TRUE` or `FALSE`. | | Offer attachment | A PDF of at most 5 MB, with at most 5 attachments per offer. | | Offer attachment path | A PDF in the listing stage at `offers//attachments/.pdf`. | Listing-level problems are translated the same way — most often the listing's targets, which must name either specific accounts (each as `organization_name.account_name`, up to 100 of them) or regions, never both. An error Snowflake does not document is shown as it arrived, so nothing is lost — forward it to [support@suger.io](mailto:support@suger.io) if it is not self-explanatory. A publish that Snowflake keeps refusing ends, within minutes, with the offer in `CREATE_FAILED` and the error recorded on it — the offer does not stay in `PENDING_CREATE`. ## Cancel a Private Offer You can cancel a pending private offer at any time before the buyer accepts it. This is useful if you need to modify the offer terms or if the offer is no longer valid. 1. Select the offer you want to cancel. 2. Click `Cancel` button. 3. Confirm the cancel in the popup dialog After cancel the offer, the offer status will change to "Withdrawn" and the buyer will no longer be able to accept the offer. You can edit the offer details and resubmit it. If Snowflake refuses the withdrawal, the offer ends in `CANCEL_FAILED` with the error recorded on it instead. ![Cancel Offer](images/snowflake-cancel-offer.jpg) --- Source: https://doc.fours.com/snowflake-marketplace/usage-metering-upload/ # Usage Metering Upload Report consumer usage to Snowflake Marketplace in bulk by uploading a CSV file. --- ## Overview For metered (usage-based) listings, you report each consumer's usage to Snowflake so it can be billed. Fours lets you submit usage for many entitlements at once by uploading a CSV — no need to call the API per consumer. :::info Usage charges can only be reported for **Connected App** listings. Standard data-share listings do not support usage metering. See the [FAQ](#faq) for details. ::: ## Upload CSV 1. Open the **Usage Records** (metering) page. 2. Click **Batch Report** to open the **Batch Report Usage Records** dialog. 3. Click **Choose File** and select your usage CSV. 4. Fours parses the file and previews the result in two tables: - **Valid Usage Records** — records matched to an entitlement and dimension, with the calculated amount. - **Invalid Usage Records** — records that could not be matched, each annotated with an error message (e.g. `buyer is not found`, `usage dimension is not found`). You can download these to fix and re-upload. 5. (Optional) Turn on **Auto Fix** to automatically map a record to the entitlement's first available dimension when the supplied dimension does not match. 6. Review the valid records, then click **Batch Report** to submit them. ## CSV format Each row is one usage record. The header row must include a column that identifies the consumer, plus `dimension` and `quantity`. **Identify the consumer with one of:** | Column | Description | |--------|-------------| | `sugerBuyerId` | Fours buyer ID | | `sugerExternalBuyerId` | Your external buyer ID | | `customerId` | Your customer ID stored on the buyer | | `sugerEntitlementId` | Fours entitlement ID | | `sugerExternalEntitlementId` | Your external entitlement ID | **Required usage columns:** | Column | Description | |--------|-------------| | `dimension` | The billable dimension / event key to charge against | | `quantity` | The number of units consumed (thousands separators like `12,238` are accepted) | Records that share the same entitlement (and the same `erpInvoiceID`, if supplied) are grouped together and the quantities for each dimension are summed before reporting. Rows with the same entitlement but different `erpInvoiceID` values are reported as separate groups. :::info The upload dialog also accepts `timestamp` and `erpInvoiceID` columns, but they do **not** affect Snowflake charges. Snowflake stamps each charge with Fours' report-generation time (grounded to the hour, for idempotent retries), so a supplied `timestamp` is ignored; `erpInvoiceID` is not sent to Snowflake. ::: :::caution A row is rejected if its consumer or entitlement cannot be found, the entitlement is not in an `ACTIVE`, `SUSPENDED`, or `PENDING_CANCEL` status, the `dimension` does not exist on the entitlement, or the `quantity` is missing or not a number. ::: ## FAQ Frequently asked questions about selling and billing on Snowflake Marketplace with Fours. ### Can I report usage charges for standard data-share listings? No. Usage charges can only be reported for **Connected App** listings. Standard data-share listings do not support usage metering. ### When will the invoice be generated? Invoicing is handled on the **Snowflake side**. Fours reports usage charges to Snowflake as they are submitted (deduplicated per hour), and Snowflake generates the invoice at the end of the billing period, aggregating all charges reported during that period. ### How do I undo or modify a charge that was already sent? Charges are **append-only** — once a charge is reported it cannot be edited or removed. If you need to correct a charge, contact **Snowflake Marketplace Ops**. --- Source: https://doc.fours.com/snowflake-marketplace/revenue/ # Revenue Track billed revenue and payouts from your Snowflake Marketplace listings in Fours. --- ## Overview Snowflake handles billing on its side — it invoices your consumers and disburses your earnings. Fours does **not** generate Snowflake invoices. Instead, Fours **ingests** the billing data Snowflake publishes to providers, stores it, and normalizes it into unified **revenue records** so Snowflake revenue sits alongside your AWS, Azure, GCP, and direct (Stripe) revenue in one place. Fours syncs two datasets from your Snowflake provider account: | Dataset | Source | What it contains | |---------|--------|------------------| | **Invoices** | Snowflake's `MARKETPLACE_LISTING_INVOICE_STATUS` view | One row per invoice Snowflake issued to a consumer — billed amount, tax, Snowflake fees, expected payout, and invoice status. | | **Disbursements** | Snowflake's `MARKETPLACE_DISBURSEMENT_REPORT` view | The payouts Snowflake sent you — each event's net amount, charge type, and event date. | Fours joins the two by invoice number and, where possible, resolves each invoice to the matching Fours buyer, product, and entitlement. ## Where to find Snowflake revenue Snowflake is a first-class channel in Fours' revenue surfaces — there is no separate Snowflake-only revenue page. To view it: 1. Open **Revenue → Revenue Records**. 2. Set the **Channel** filter to **Snowflake**. The **Multi-Channel Revenue** workspace (analytics, channel performance, cash & disbursements, and reports) also includes Snowflake wherever a channel filter is available. See the [Revenue Records](/revenue/revenue-records/) documentation for the full page reference. You can also see the Snowflake revenue records for a single consumer on that **Buyer**'s detail page, or for a single **entitlement** on its detail view. ## What each amount means For a Snowflake invoice, Fours maps the raw values into the normalized revenue record as follows: | Revenue record field | Snowflake source | Meaning | |----------------------|------------------|---------| | **Billed** | `total_billed_amount` | What Snowflake billed the consumer. | | **Collectable** | `expected_payout_amount` | What you receive after Snowflake's marketplace fees. | | **Tax** | `sales_tax_amount` | Sales tax collected on the invoice. | | **Disburse amount** | Σ disbursement `net_amount` | Actual money paid out to you, summed across disbursement events for the invoice. | | **Disburse date** | latest disbursement `event_date` | When the most recent payout for the invoice occurred. | | **Invoice date / status** | `invoice_date` / `invoice_status` | The invoice's date and current status. | :::info **Void invoices** are kept in the record for auditability, but their billed, collectable, tax, and payout amounts are zeroed out so they don't inflate your totals. ::: ## Sync Revenue sync runs automatically once your Snowflake Marketplace integration is connected. Fours periodically pulls new invoice and disbursement rows and updates the corresponding revenue records. - The **first** sync performs a historical backfill of all available invoices and disbursements; subsequent syncs are incremental. - If you disable and later re-enable revenue sync on the Snowflake integration, Fours re-runs the historical backfill so no records are missed. :::caution Snowflake revenue data reflects what Snowflake reports in its provider views. If an invoice or payout is missing, confirm it appears in your Snowflake account first — Fours can only surface what Snowflake has published. ::: ## FAQ ### Does Fours generate Snowflake invoices? No. Snowflake generates the invoices and issues payouts. Fours reads Snowflake's provider billing views and normalizes them into revenue records. To learn how usage charges get to Snowflake in the first place, see [Usage Metering Upload](/snowflake-marketplace/usage-metering-upload/). ### Why is my collectable amount lower than the billed amount? The collectable amount is the **expected payout** — the billed amount minus Snowflake's marketplace fees. Snowflake nets its fees before disbursing your earnings. ### When will I see a disbursement? A disbursement appears once Snowflake reports the payout in `MARKETPLACE_DISBURSEMENT_REPORT` and Fours' next sync ingests it. Until then, the record shows the expected payout (collectable) without a disburse date or amount. --- Source: https://doc.fours.com/snowflake-marketplace/ # Snowflake Marketplace Snowflake Marketplace works differently from the hyperscaler marketplaces: what you sell is a data product or an application, your customers are called **consumers**, and they are identified by a Snowflake account identifier rather than a cloud account or tenant ID. Becoming a provider is a prerequisite you complete in Snowflake before Fours is involved — you need a full Snowflake account (trial and reader accounts cannot list), the ACCOUNTADMIN role or a role with provider privileges, and the accepted Provider and Consumer Terms. There is one more step here that the other marketplaces do not have: a **provider profile** representing your company must exist before you can publish any paid listing. Fours connects to your Snowflake account with key-pair authentication, then manages listings, pricing plans, private offers, usage reporting, and revenue from the console. ## The path to your first Snowflake sale 1. **[Integration](/snowflake-marketplace/integration/)** — confirm your account qualifies as a provider, generate a key pair, and connect with your account, user, and private key. 2. **[Provider Profile](/snowflake-marketplace/provider_profile/)** — the company identity consumers see, including the consumer contact address Snowflake expects you to answer within 24 hours. 3. **[Pricing Plan](/snowflake-marketplace/pricing_plans/)** — usage-based and subscription-based plans, and the per-query, monthly-fee, and billable-event charging options behind them. 4. **[List Product](/snowflake-marketplace/list_product/)** — create the listing in Provider Studio and decide whether it is public on the Marketplace or shared with specified consumers only. 5. **[Create Private Offer](/snowflake-marketplace/create-private-offer/)** — discount a published pricing plan for one consumer, or charge a flat one-time contract value with optional installments. ## After a consumer subscribes - **[Usage Metering Upload](/snowflake-marketplace/usage-metering-upload/)** — report consumption for many entitlements at once by uploading a CSV, with a validation preview before anything is submitted. - **[Revenue](/snowflake-marketplace/revenue/)** — how Fours joins Snowflake's invoice and disbursement provider views by invoice number so billed amounts, fees, and payouts line up with your other channels. ## Scope and limits :::info Usage charges can only be reported for **Connected App** listings. Standard data-share listings do not support usage metering. Snowflake usage is reported by CSV upload rather than per-consumer API calls, so plan for a batch cadence rather than continuous metering. A Snowflake integration cannot be edited after it is created — to change the account, user, or key, delete it and connect again. Deleting removes the stored private key immediately and permanently. Snowflake revenue appears in [Revenue Records](/revenue/revenue-records/) under the Snowflake channel filter — the Overview dashboard's channel filter does not list it — and there is no Snowflake-only revenue page in the console. ::: --- Source: https://doc.fours.com/alibaba-marketplace/integration/ # Integration Connect Fours to Alibaba Cloud Marketplace to list your SaaS products, manage offers, sync entitlements, and report usage — across both China (domestic) and international markets. --- ## Overview Alibaba Cloud Marketplace connects Alibaba Cloud customers with trusted SaaS providers and ISVs worldwide. Regardless of the region you sell in, the operational logic stays consistent with the other major clouds: | Concept | [Alibaba Cloud](https://marketplace.alibabacloud.com/) equivalent | Fours function | |---------|------------------------------------------------------------------|----------------| | Listing | Marketplace Product | Centralized product catalog management | | Offer | Private Quote / Pricing | Automated creation of custom contract terms | | Entitlement | Instance / Subscription | Real-time provisioning and access control | :::info **Org-Level only.** Alibaba Marketplace connects with organization-wide API credentials and does not support user-level integrations. ::: ## Prerequisites To establish a secure handshake between Fours and Alibaba Cloud, gather four pieces of information from your Alibaba Cloud account: - **Alibaba Cloud Account ID** — your unique root account **Uid** (aliyunUid). - **Access Key ID** — the public identifier for your API credentials. - **Access Key Secret** — the private key for API authentication. - **SPI Key** — the [Service Provider Interface](https://www.alibabacloud.com/help/en/marketplace/latest/spi-security-scheme) key, used to verify security for notification events (such as a customer purchase). You will also need the **Region ID** you sell in (e.g. `cn-beijing` for China, or an international region). ## Connect Link your Alibaba Cloud credentials to Fours to enable automated order management and revenue recognition. 1. Navigate to **Settings > Integrations** and locate the **Alibaba Marketplace** card. Click **Connect**. 2. Enter your **Region ID**, **Cloud Account ID** (root account Uid), **Access Key ID**, **Access Key Secret**, and **SPI Key**. 3. (Optional) Enter the **Product Code(s)** you want to list — these can also be configured later. 4. Click **Create** (or **Verify**) to validate the credentials and confirm the connection. :::note The Region ID determines whether Fours uses the Alibaba Cloud **domestic (China)** or **international** SDK. Access keys and the SPI key are stored in Fours' secret store and are never persisted in plain text. ::: ## Manage settings Once connected, you can fine-tune how Fours interacts with your Alibaba listings from the integration's edit menu: - **Product Fetching** — by default, Fours fetches all products under your Account ID. To limit this, manually enter specific **Product Code(s)**. - **Metering Control** — toggle **Usage Metering Disabled** if you need to pause usage reporting to Alibaba. - **Renewal Notifications** — enable **Entitlement End Soon** alerts to notify your team by email (10–60 days in advance) when a buyer's contract is approaching its end date. ## Auth-Free URL redirection Let your buyers reach your backend directly from the Alibaba Console without re-authenticating. When a buyer opens your service, Fours signs the request with your SPI Key and redirects the buyer to your **Fulfillment URL** with a token you verify on your side. 1. **Configure fulfillment** — set your fulfillment URL in the Alibaba Marketplace to point to the Fours service. 2. **Redirection flow** — when a buyer clicks to access your service, Fours resolves the entitlement, signs the request with your SPI Key, and redirects the buyer to your Fulfillment URL: ``` https:///?sugerEntitlementId=&partner=alibaba×tamp=&token= ``` | Parameter | Value | |---|---| | `sugerEntitlementId` | The Fours entitlement (contract) ID. | | `partner` | The literal string `alibaba` (lowercase). | | `timestamp` | The event time in RFC 3339 UTC, e.g. `2026-01-15T09:30:00Z`. | | `token` | A 32-character lowercase-hex signature (see below). | 3. **Verify on your backend** — recompute the signature from the query parameters and your SPI Key and compare it to `token` before you trust the redirect. ```d2 shape: sequence_diagram buyer: Buyer alibaba: Alibaba Console suger: Fours backend: Your backend buyer -> alibaba: "Click \"Access service\"" alibaba -> suger: "Open the auth-free URL (SPI webhook)" suger -> suger: "Resolve entitlement, sign params with SPI Key (MD5)" suger -> buyer: "303 redirect to your Fulfillment URL with signed params" { style.stroke-dash: 4 } buyer -> backend: "GET Fulfillment URL (sugerEntitlementId, partner, timestamp, token)" backend -> backend: "Recompute MD5(params + \"&key=\" + SPI Key), compare to token" matches: "if token matches" { backend -> buyer: "Grant access (log the buyer in)" { style.stroke-dash: 4 } } mismatch: "else — mismatch or stale timestamp" { backend -> buyer: "Reject the request" { style.stroke-dash: 4 } } ``` ### Validation contract The `token` is a **lowercase-hexadecimal MD5** digest of the UTF-8 bytes of the signed string. Build the signed string, hash it, and compare: 1. Take the redirect's query string and **remove the `token` parameter**. Keep every other parameter **in the exact order received** — `sugerEntitlementId`, then `partner`, then `timestamp`. **Do not sort or re-encode the parameters.** 2. Append `&key=` to that string. 3. Compute `md5(...)` over the UTF-8 bytes and hex-encode it in lowercase. 4. Compare the result to the received `token` using a **constant-time** comparison. So the string you hash is: ``` sugerEntitlementId=&partner=alibaba×tamp=&key= ``` **Worked example.** With SPI Key `my-spi-key`, entitlement `ent-abc123`, and timestamp `2026-01-15T09:30:00Z`, the signed string is: ``` sugerEntitlementId=ent-abc123&partner=alibaba×tamp=2026-01-15T09:30:00Z&key=my-spi-key ``` and `token` = `bd6b70b1b180ec9d0f8ed112d8b18129`. :::warning **Fours does not enforce expiry or replay protection on this redirect.** The `timestamp` is signed (so it cannot be tampered with) but Fours never rejects an old one, and the same `token` validates indefinitely. If you need freshness or one-time use, **enforce your own maximum age on `timestamp` and your own replay/dedup** on your backend. ::: The SPI Key used to sign is the same **SPI Key** you configured on the integration. Keep it secret; anyone with it can forge a valid redirect. ### Reference validators #### Go ```go import ( "crypto/md5" "crypto/subtle" "encoding/hex" "strings" ) // validateRedirect verifies the Alibaba auth-free redirect token. // rawQuery is the URL query string exactly as received, e.g. // "sugerEntitlementId=ent-abc123&partner=alibaba×tamp=2026-01-15T09:30:00Z&token=bd6b...". func validateRedirect(rawQuery, spiKey string) bool { var received string kept := make([]string, 0) for _, p := range strings.Split(strings.TrimPrefix(rawQuery, "?"), "&") { if strings.HasPrefix(p, "token=") { received = strings.TrimPrefix(p, "token=") continue } kept = append(kept, p) // keep received order; do NOT sort } sum := md5.Sum([]byte(strings.Join(kept, "&") + "&key=" + spiKey)) expected := hex.EncodeToString(sum[:]) return subtle.ConstantTimeCompare([]byte(received), []byte(expected)) == 1 } ``` #### Python ```python import hashlib import hmac def validate_redirect(raw_query: str, spi_key: str) -> bool: received = "" kept = [] for p in raw_query.lstrip("?").split("&"): if p.startswith("token="): received = p[len("token="):] else: kept.append(p) # keep received order; do NOT sort string_to_sign = "&".join(kept) + "&key=" + spi_key expected = hashlib.md5(string_to_sign.encode("utf-8")).hexdigest() return hmac.compare_digest(received, expected) ``` #### TypeScript ```ts import { createHash, timingSafeEqual } from "node:crypto"; function validateRedirect(rawQuery: string, spiKey: string): boolean { let received = ""; const kept: string[] = []; for (const p of rawQuery.replace(/^\?/, "").split("&")) { if (p.startsWith("token=")) received = p.slice("token=".length); else kept.push(p); // keep received order; do NOT sort } const expected = createHash("md5") .update(kept.join("&") + "&key=" + spiKey, "utf8") .digest("hex"); const a = Buffer.from(received); const b = Buffer.from(expected); return a.length === b.length && timingSafeEqual(a, b); } ``` ## Edit / Delete You can update your **Account ID** or **Product Codes** at any time by editing the integration. To rotate security-sensitive keys (such as the **Access Key Secret** or **SPI Key**), delete the integration and reconnect with the new credentials. Deleting the integration immediately erases all stored API and SPI keys from Fours and stops product sync, entitlement processing, and metering. This won't delete your products on Alibaba, but automated syncing and entitlement tracking stay paused until you manually reconnect. :::warning Deleting the integration may affect active marketplace subscriptions and billing relationships. ::: --- Source: https://doc.fours.com/alibaba-marketplace/list-product/ # List Product ## Overview Fours syncs your published products from Alibaba Cloud Marketplace so you can manage them alongside your other marketplaces. ## How product sync works - Fours periodically fetches your marketplace products and creates or updates the matching Fours products. - Product metadata — SKUs, pricing dimensions, and plan details — is imported from the marketplace listing. - Products you publish or update on Alibaba Cloud Marketplace are reflected in Fours on the next sync. To list a new product, publish it on Alibaba Cloud Marketplace (optionally scoping the integration to specific **Product Codes**); Fours imports it automatically. --- Source: https://doc.fours.com/alibaba-marketplace/pricing-and-offers/ # Pricing & Offers ## Pricing Alibaba Cloud Marketplace products carry their pricing **dimensions** and commit options from the marketplace listing. Fours imports these when it syncs the product, so the offer reflects the plan you configured on Alibaba Cloud. ## Offers For each synced product, Fours maintains a **default offer** that mirrors the product's public marketplace pricing. The default offer pulls its dimensions, commitments, and currency from the product. :::note Alibaba Cloud Marketplace uses a single default (public) offer per product. Buyer-specific private offers, channel offers (CPPO), and offer-acceptance flows are **not** part of the Alibaba integration — purchases are completed directly on Alibaba Cloud Marketplace. ::: --- Source: https://doc.fours.com/alibaba-marketplace/entitlements/ # Entitlements ## Overview When a buyer subscribes to your product on Alibaba Cloud Marketplace, Fours creates and maintains an **entitlement** that tracks the subscription lifecycle. Marketplace events (and periodic sync) drive the entitlement state. ## Lifecycle | Marketplace event | Fours action | |-------------------|--------------| | Create instance | Creates the entitlement | | Renew instance | Extends the entitlement term | | Upgrade instance | Updates the entitlement's plan | | Expire instance | Suspends the entitlement | | Release instance | Cancels the entitlement | Fours also periodically **syncs entitlements** from the marketplace to reconcile any events it may have missed. Trial subscriptions are recognized and flagged. ## Auto-cancel suspended entitlements Suspended (expired) entitlements can be **automatically cancelled** after a configurable number of days. You can also configure how many days before an entitlement ends Fours sends an expiry notification. --- Source: https://doc.fours.com/alibaba-marketplace/usage-metering/ # Usage Metering ## Overview For usage-based products, Fours reports metered usage back to Alibaba Cloud Marketplace so buyers are billed for what they consume. ## Metering key types Fours supports four Alibaba metering key types: | Type | Meaning | |------|---------| | **Frequency** | A count of events or occurrences | | **Unit** | A quantity of units consumed | | **Period** | A duration in **hours** | | **PeriodMin** | A duration in **minutes** | ## Reporting rules - Usage must be reported within the **current hourly window** — Alibaba buckets metering by the hour. - Metering can be turned off per integration via the **Usage Metering Disabled** setting. Fours sends usage to the marketplace's metering API as it is recorded, so your consumption-based charges stay accurate. --- Source: https://doc.fours.com/alibaba-marketplace/ # Alibaba Marketplace Alibaba Cloud Marketplace is the one channel here that covers both the **China (domestic)** and **international** markets from the same integration — the Region ID you enter decides which Alibaba Cloud endpoint Fours talks to. It also inverts the usual direction of work. On the other marketplaces you build a listing in Fours and Fours publishes it; on Alibaba Cloud you publish the product on the marketplace and Fours imports it, then takes over the transactional side: entitlement lifecycle, renewal notifications, and usage reporting. Because purchases are completed on Alibaba Cloud Marketplace itself, there are no buyer-specific private offers, no channel partner offers, and no offer-acceptance step. Each product carries a single default offer that mirrors its public marketplace pricing. The integration is organization-wide only, and connects with your Alibaba Cloud account ID, an access key pair, and an SPI key. ## Connect and bring your catalog in 1. **[Integration](/alibaba-marketplace/integration/)** — the four credentials to gather, how the Region ID selects the domestic or international endpoint, and the signed auth-free redirect that logs a buyer into your backend straight from the Alibaba Console. 2. **[List Product](/alibaba-marketplace/list-product/)** — how the periodic sync imports products you have published, including SKUs and plan details, and how to scope the sync to specific product codes. 3. **[Pricing & Offers](/alibaba-marketplace/pricing-and-offers/)** — where a product's dimensions and commit options come from, and what the single default offer per product does and does not let you do. ## Keep subscriptions and usage in sync - **[Entitlements](/alibaba-marketplace/entitlements/)** — the marketplace events that create, extend, upgrade, suspend, and cancel a subscription, plus auto-cancellation of suspended entitlements and advance expiry alerts. - **[Usage Metering](/alibaba-marketplace/usage-metering/)** — the four Alibaba metering key types, and the hourly window your usage has to land in to be billed. ## Scope and limits :::info Alibaba Cloud Marketplace connects at the **organization level** only — there is no user-level integration. Fours does not create or publish Alibaba listings. Publish the product on Alibaba Cloud Marketplace and Fours imports it on the next sync. Private offers, channel partner offers (CPPO), and offer acceptance are not part of this integration; buyers purchase the public listing directly on Alibaba Cloud Marketplace. This section has no separate revenue guide. Usage reporting can be paused per integration with the **Usage Metering Disabled** setting. ::: --- Source: https://doc.fours.com/cosell/cosell-configuration/ # Configuration Configure to automate your co-sell flow. --- ## Overview Once you have completed integrations with your CRM and the cloud partners, you will need to configure the field mappings, templates, and other options before starting making referrals. Co-sell settings act as the translation layer between your CRM (Salesforce, HubSpot, or Dynamics 365) and cloud partner portals — AWS Partner Central, Azure Co-Sell, and Google Cloud Partner Network. Once configured, your sales team can register deals and track referrals without leaving their CRM or manually re-entering data in each partner portal. :::info - Visit [Fours Integrations](https://console.suger.io/settings?tab=integrations) to find and configure supported partners. - Configurations affect both Fours Console and Suger Connector in CRM software. - Click the History button for change log and audit records button at any time to access the change log and review data audit records. ::: ### Prerequisites Before you begin, make sure: - You have admin access in the Fours Console. Co-sell configuration lives on the **Settings** tab of the **Co-Sell** page ([open it](https://console.suger.io/cosell?tab=settings)), which moved there from the console's main **Settings** page. An old `settings?tab=cosell` link still lands on it. - Salesforce, HubSpot, or Dynamics 365 is already connected under **Settings > Integrations**. ## Display Setting of Co-sell Intelligence Co-sell Intelligence surfaces AWS, Azure, and GCP engagement signals (Low/Medium/High) directly in your CRM widget. > Co-sell Intelligence display settings overview :::info **Co-sell Intelligence signals are enabled by Fours.** The enable toggles — the master **Enable Cosell Intelligence Signals** switch and the per-partner **AWS Signals**, **Azure Signals**, and **GCP Signals** switches — are not available to customers in **Co-Sell › Settings**: its **Intelligence** sub-tab renders nothing for your team. To turn these signals on or off, or to change which cloud partners they cover, contact [support@suger.io](mailto:support@suger.io). ::: Once Fours has enabled them, signals surface per cloud partner. A partner that has not been switched on shows no data even while Co-sell Intelligence itself is on, so tell support which of AWS, Azure, and GCP you want covered. ### Three different "enrichment" features Three features share the word *enrichment* but do different things. Keep them apart when you configure or troubleshoot: | Feature | What it fills | When it runs | | --- | --- | --- | | **[Auto-Enrich Referrals](#auto-enrich-referrals)** | Blank **referral** fields — company address, website, contact details — on the referral you are about to share | At share time, when the referral is previewed or prepared | | **CRM intelligence-signal enrichment** | Intelligence **signals** written into mapped fields on your Salesforce Account/Opportunity or HubSpot Deal/Company records | On a schedule, every **2 hours** (previously every 12 hours) | | **[AWS lead enrichment](/cosell/cosell-leads/#create-leads-from-salesforce-accounts)** | New AWS **leads**, created from your Salesforce Accounts, with what AWS knows about each company | Once a day at 03:15 UTC while its automation is on. Set it up on the **Lead Enrichment** sub-tab of **Co-Sell › Settings**, which appears only when a verified Salesforce integration is connected | ![The co-sell configuration's Settings tab — the Auto-Share Referrals and Auto-Enrich Referrals toggles, each with its own description](images/50-cosell-settings-toggles.png) Auto-Enrich never touches your CRM objects — it only completes the outgoing referral. Intelligence-signal enrichment never touches referral fields — it only writes signals into the CRM fields you have mapped for them. Lead enrichment fills neither: it reads your Salesforce Accounts and creates new AWS leads from them. #### The 14 intelligence signals Intelligence-signal enrichment writes 14 values: | Cloud partner | Signals | | --- | --- | | **AWS** | AWS Engagement Score · AWS Marketplace Count · AWS Marketplace Review Count · AWS Marketplace Purchase Count | | **Azure** | Azure Engagement Score · Azure Event Score · Azure Usage Score · Azure Marketplace Count · Azure Marketplace Review Count · Azure Marketplace Purchase Count | | **GCP** | GCP Engagement Score · GCP Marketplace Count · GCP Marketplace Review Count · GCP Marketplace Purchase Count | The engagement score rates how likely the customer is to be won through that partner's co-sell motion. The marketplace counts describe the customer's own footprint on that marketplace — products listed, reviews on those products, and purchases made. Azure adds two extra scores: **Event Score** (how many interactions the customer has had with Microsoft) and **Usage Score** (how much the customer uses Azure services). Each signal is written only to the Salesforce or HubSpot field you map it to. Signals with no mapped field are simply not written. ## Create a new configuration Each configuration is a dedicated bridge between one CRM source and one cloud partner network. 1. Open the **Co-Sell** page and select its **Settings** tab ([open it](https://console.suger.io/cosell?tab=settings§ion=configs)). 2. Select the **Configs** sub-tab, and click the `New Config` button in the **Cosell Configs** header. The **Settings** tab opens on its **Intelligence** sub-tab, which is empty for your team, so switch to **Configs** first. > New Config button in the Co-sell settings menu 3. Choose the **CRM Partner** and the **Cloud Partner** to proceed. | Picker | Options | | --- | --- | | **CRM Partner** | `SALESFORCE`, `HUBSPOT`, `DYNAMICS365` | | **Cloud Partner** | `AWS`, `AZURE`, `GCP`, and `SUGER` | Each picker lists only the partners your organization has actually connected, so a CRM or cloud you have not integrated does not appear. `SUGER` is offered as a cloud partner only when Partner Management (PRM) is enabled for your organization. :::warning Only one active configuration is allowed per hyperscaler (e.g., one for AWS, one for GCP). You can't run two AWS configs side by side, even across different CRMs. To change an existing configuration, edit it rather than creating a second one. ::: ![A sample Settings > Co-sell page with all configurations](images/set-up-co-sell-in-settings-3.png) ## Outbound Setting The Outbound Sync section defines the data flow **from your CRM platform to Cloud Partners**, indicating that information is pushed outward from the CRM system. ### Field Mapping Field mapping configuration is used to control how fields are pre-filled when you create a new referral share from CRM to Cloud Partners. If the auto-share referrals setting is turned on, this configuration will be applied to all automatically shared referrals. It also affects the Suger Connector in CRM software. In the configuration table, the title of each row represents the field name in the Cloud Partner. You can use the search dropdown to select which CRM field should be mapped to it. You can add or remove Cloud Partner fields to customize your own mapping rules. The column captions name both ends of the flow: the partner's field on the left (for example **AWS Partner Central field**), the CRM source in the middle (for example **Source in Salesforce · data flows Salesforce → AWS (Outbound)**), and **Value source** above each row's method buttons. On **AWS** and **Azure** configurations the rows are grouped into sections — on AWS, *Customer information*, *Project information*, *Contacts*, *Lifecycle & revenue*, and *Software revenue & contract terms*. Drag a row by its handle (**Drag to reorder**) to move it; on AWS and Azure a row can only move within its own section. GCP and Fours partner (`SUGER`) configurations show one list. Some fields may be marked with an asterisk (*), which means they are required fields and must be filled in before submission. Use **Formula** — which also holds picklist value mapping on outbound rows — to define complex data-mapping rules, including conditional logic, value conversions, and cross-field mappings. See [Expression Mode](#expression-mode) and [Picklist Value Mapping](#picklist-value-mapping) for detailed documentation and examples. For each partner field, choose one of four mapping methods. Each outbound row has a labelled button per method — **Default**, **Formula**, and **AI** (the last only on fields that support it) — and leaving all three off maps the field directly from the CRM field you pick: | Mapping Method | Use case | Example | | --- | --- | --- | | **Default Value** (**Default**) | A hard-coded value sent for every referral. Best for information that's mandatory for the partner but identical across your company — Partner ID, alliances team alias, sales-lead email, listing ID. | `Sales_Lead_Email` → `alliances@company.com` | | **Direct & Picklist Mapping** | Links a CRM field 1:1 to a partner field. For dropdowns, map every active CRM value to a partner-approved value — on outbound rows, with the **Picklist** recipe inside **Formula**. Best for standard fields like Close Date, or aligning deal stages to partner stages. | `Opportunity.CloseDate` → `Partner.Target_Close_Date` | | **Formula** (Expression Mode) | A dynamic logic engine using Go Templates (`text/template`) syntax — calculations, concatenations, fallbacks, and cross-field lookups. Build one from a recipe, or write the template yourself. | `{{- multiply .Amount 0.8 -}}` (net revenue) or `{{.Name}} {{.Account.Name}}` (unique title) | | **AI Generate** (**AI**) | Describe the value you want in a natural-language prompt and Fours generates it with AI when the referral is shared. You can reference source fields with `{{.FieldName}}`. Available on five supported AWS ACE fields: Industry Vertical, Partner Primary Need from AWS, Postal Code, Customer Business Problem, and Estimated AWS Monthly Recurring Revenue. | `Write a business problem statement based on {{.Description}}` | :::info For the **Customer Business Problem** field, Fours automatically instructs the AI to produce 500–1,800 characters and truncates any output over 1,800 characters. The built-in rule takes precedence over any other length guidance in the AI prompt. ::: :::warning You must map every active CRM stage (e.g., "Discovery") to a partner-approved value (e.g., "Prospecting"), or the sync will fail during stage transitions. ::: ![Picklist value mapping between CRM stages and partner stages](images/understand-the-fields-mapping-in-co-sell-2.png) #### Items that need attention Every outbound configuration shows a summary line above its **Field Mapping** and **Settings** steps that says whether anything in the mapping needs fixing. When nothing does, it reads **All N required fields ready** (or **Nothing needs attention**). Otherwise it reads **N items need attention.** and lists every issue, each with a **Review ›** link that scrolls to the row. The row itself is outlined in amber with the same hint. Four things are flagged: | Flagged row | Fix | | --- | --- | | **Default** is selected but the value is empty | Enter a value, or map a CRM field instead | | **AI** is selected but there is no prompt | Describe what to generate | | **Formula** is selected but the formula is empty | Finish it, or pick another method | | A required field has no CRM field mapped | Map a CRM field, or use another method | An optional field you leave unmapped is not flagged. The summary updates as you edit; it reports issues and does not stop you saving. #### Software revenue fields (AWS) AWS accepts the five software-revenue fields only from organizations whose AWS ACE partner type is **ISV Accelerator Program Partner** or **SaaS Revenue Recognition Program**: | Field | Target | | --- | --- | | Customer Software Value | `SoftwareRevenue.Value.Amount` | | Customer Software Value CurrencyCode | `SoftwareRevenue.Value.CurrencyCode` | | Procurement Type | `SoftwareRevenue.DeliveryModel` | | Contract Start Date | `SoftwareRevenue.EffectiveDate` | | Contract End Date | `SoftwareRevenue.ExpirationDate` | For any other partner type, or none, a value mapped to these fields never reaches AWS. So on an AWS outbound configuration (from Salesforce, HubSpot, or Dynamics 365) those rows appear read-only under **Software revenue fields (read-only)**, with a note naming your current partner type, and in the add-field list they are disabled with the hint *Requires ISV Accelerator or SaaS Revenue Recognition partner type*. To use them, set **Partner Type** on your AWS ACE integration under **Settings > Integrations** (see [AWS Partner Central (ACE)](/integrations/aws-partner-network-api/)). For an eligible partner type, Fours fills any of the five you leave blank — see [Auto-filled / normalized by Fours](/cosell/cosell-referral-api/#auto-filled--normalized-by-fours). ### Sync Fields The Sync Fields configuration controls **whether Fours will update an item to Cloud Partners at the next scheduled sync time** when a corresponding field value changes in the CRM. To enable syncing for a specific field, turn on the **Enable Syncing** toggle on the right side of the field. > Enable Syncing toggle in the Sync Fields table You can configure the following options: * **Conditional sync with Expression Mode:** Click **Formula** next to a field (**Expression** on inbound rows) to enable Expression Mode, which allows you to define **conditional synchronization rules** based on custom logic. Refer to the section below for details on using Expression Mode. * **Picklist values mapping:** Use this feature to define custom value mappings between CRM and Cloud Partner fields. Refer to the related section below for details on using Picklist values mapping. * **Add a Cloud Partner field:** Scroll down the page and search for a field name under the selected Cloud Partner in the lower-left panel. Click the field to add it to the configuration list. > Adding a Cloud Partner field to the sync configuration ### Settings The referral automation settings allow you to automatically manage the referral sharing workflow from your CRM to Cloud Partner. ![A sample co-sell configuration with both Auto-Enrich and Auto-Share toggles enabled](images/set-up-co-sell-in-settings-5.png) #### Auto-Share Referrals Automatically share all eligible opportunities from your CRM to Cloud Partner. When this option is enabled, any opportunity that meets the sharing criteria will be submitted without manual action. :::info **Auto-share runs every 3 hours.** This cadence is fixed and identical for every cloud partner — there is no per-configuration schedule to set. An opportunity that becomes eligible between runs is picked up on the next cycle. ::: ##### Salesforce Only – Conditional Criteria Setting The **Criteria** field under **Auto-Share Referrals** narrows auto-share to the records you want. Only records that meet the condition are included in the next auto-share cycle. You can express that condition two ways, using the segmented tabs at the top of the Criteria editor: | Tab | What you get | | --- | --- | | **Builder** | A visual condition tree — pick a field, an operator, and a value, and combine rows with AND / OR groups. No SOQL syntax to remember. | | **Advanced (SOQL)** | The raw **Salesforce SOQL** predicate, evaluated in the context of the selected Salesforce object. | :::note The two tabs are two views of **one** value. Whatever you build visually is saved as the SOQL string — the visual tree itself is never stored. When you reopen the configuration, Fours re-parses the saved SOQL back into the Builder. ::: Some SOQL cannot be represented as a visual tree — subqueries, function calls, and unary `NOT`. When Fours cannot parse the saved predicate it keeps you on the **Advanced (SOQL)** tab and shows: *"This query can't be edited in the Builder — keep it in Advanced (SOQL)."* The predicate still works; it just has no Builder equivalent. **Operators available in the Builder** The operator list depends on the type of the field you pick: | Field type | Operators | | --- | --- | | **String / picklist** | `=`, `!=`, contains, not contains, starts with, not starts with, ends with, not ends with, is blank, is not blank, `IN`, `NOT IN` | | **Number / date / datetime** | `=`, `!=`, `>`, `<`, `>=`, `<=` | | **Boolean** | `=`, `!=` | **Date values** can be entered two ways: | Mode | What you pick | | --- | --- | | **Absolute** | A specific date from the calendar picker. | | **Relative** | A rolling Salesforce date literal: `TODAY`, `YESTERDAY`, `LAST_N_DAYS:7`, `LAST_N_DAYS:30`, `LAST_N_DAYS:90`, `LAST_90_DAYS`, `NEXT_90_DAYS`, `THIS_QUARTER`, `THIS_MONTH`. | Use Relative when you want the window to move with time — for example, opportunities created in `LAST_N_DAYS:30` stays current without editing the criteria each month. **How Advanced (SOQL) is evaluated:** Fours embeds your predicate into a SOQL query. - By default, `` is **Opportunity**. Other object can also be used by calling object name. - For SOQL syntax and operators, refer to the [official guide](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql.htm). - Field availability: **Salesforce → Setup → Object Manager → \ → Fields & Relationships**. Use the **Field Name**. :::note * Field names must match CRM field names exactly (case-sensitive). * Use **single quotes** for strings. * Invalid syntax will cause the auto-share to fail. * Use the **Preview matches** button to check which records match the current criteria before saving changes. ::: **Preview matches** Click **Preview matches** to run the current criteria against Salesforce without saving. The **Opportunities matching your criteria** panel lists what came back, with one row per opportunity: | Column | What it shows | | --- | --- | | **ID** | The Salesforce opportunity ID | | **Name** | The opportunity name | | **Stage** | The current Salesforce stage | | **Amount** | The opportunity amount | An empty result means the criteria matches nothing right now — worth checking before you enable auto-share and wonder why nothing is being shared. ##### HubSpot Only – List Setting The Segment feature in HubSpot (previously called List) can be used as a **sync filter**. To apply this filter, search for and add the **Segment ID** (also referred to as List ID) to include only items belonging to that segment in the sync process. See [HubSpot documentation](https://knowledge.hubspot.com/segments/create-active-or-static-lists) for more details. You can find the Segment ID in: **HubSpot → CRM → Segments → \ → Details → ILS Segment ID** --- #### Auto-Enrich Referrals Save time and improve data quality by automatically filling in missing company and contact information when sharing referrals with Cloud Partners. The Auto-Enrich feature uses **Fours AI** to complete incomplete records, ensuring your referrals contain all necessary details for successful partner engagement. :::note Auto-Enrich fills blank **referral** fields at share time. It is a different feature from **CRM intelligence-signal enrichment**, which writes engagement and marketplace signals into your CRM records on a schedule — see [Three different "enrichment" features](#three-different-enrichment-features). ::: ##### How It Works When you preview or prepare a referral before sharing it with a Cloud Partner, **Fours AI** automatically enriches missing data such as company address, website, and contact information. This process runs seamlessly in the background — you’ll see the updated information directly in your preview. Only empty fields are enriched; existing data in your CRM remains unchanged. ##### Minimum Information Required For enrichment to work effectively, your CRM record must contain at least: **Company information:** - Company name, or - Company website/domain **Contact information:** - Contact email address, or - Contact first and last name (with company information) If these fields are missing, Fours AI cannot retrieve additional information for that record. ##### What Fields Can Be Enriched | Cloud Partner | Company Information | Contact Information | |----------------|--------------------|---------------------| | **AWS** | Company name and website
Full address (country, state, city, postal code)
Industry classification | Email address
First and last name
Job title | | **Azure** | Company name
Full address (country, state, city, street address, postal code) | Email address
First and last name
Job title | | **GCP** | Organization name and domain
Full address (country, state/province, city, street, postal code)
Industry classification
Region and employee count | Email address
First and last name (given name and family name) | :::note - Only empty fields are enriched; existing CRM data is never overwritten. - Enrichment accuracy depends on available company and contact data. - Some fields may vary by partner integration. ::: --- #### Auto-Delete Referrals Enable Auto-Delete to automatically remove referrals that are rejected by **the Cloud Partner**. When this option is turned on, once a referral is rejected, Fours will delete the corresponding **opportunity/deal** in your CRM and soft-delete the referral in the Fours Console. By default, soft-deleted referrals are **hidden from view** and **cannot be reused or referenced**. --- #### Auto-Link Referrals (AWS only) Auto-Link attaches an accepted AWS Marketplace private offer to the AWS referral for the same deal, so the ACE opportunity records the offer the deal transacted through. It is switched on for your whole organization, on the AWS ACE integration rather than in this configuration: in **Settings > Integrations**, click **Edit** on your AWS ACE integration and turn on **Auto-Link Referrals**. It works only on an ACE integration that uses the Partner Central API. > Edit Integration dialog for AWS ACE (Partner Central API), with the Auto-Link Referrals switch turned on at the top, above Auto-Accept Referrals and the other ACE switches An offer and a referral belong to the same deal when both carry the same Salesforce opportunity, HubSpot deal, or Dynamics 365 opportunity. Fours links them: - **When the buyer accepts the offer**, if the matching referral is already in Fours. - **Every 4 hours**, for any accepted offer that is still unlinked — for example because its referral reached Fours after the offer was accepted, or because the link was removed. ```d2 direction: down accepted: "Buyer accepts the AWS\nMarketplace private offer" run: "Every 4 hours:\naccepted offers still unlinked" match: "Approved AWS referral\nfor the same deal?" { shape: diamond } wait: "Not linked yet —\nthe next run tries again" has: "ACE opportunity already\nhas an offer?" { shape: diamond } keep: "Left as it is" linked: "Offer linked to the\nACE opportunity" accepted -> match run -> match match -> wait: "no" match -> has: "yes" has -> keep: "yes" has -> linked: "no — at any ACE stage" ``` A referral can be linked when its AWS review status is **Approved** and no offer is linked to it yet, **at any ACE stage, including Launched**: sellers often launch the opportunity before the buyer accepts the offer, and AWS accepts the link. Each accepted offer is linked to one referral at most, and a CPPO resale authorization you issue to a channel partner is never linked. When the ACE opportunity already has an offer, Fours leaves it as it is. Because the 4-hour run links any matching accepted offer that is still unlinked, a link that is removed — in AWS Partner Central, or with **Unlink Offer** — is made again by a later run once Fours has synced the removal, for as long as Auto-Link is on. :::note Changing the linked offer **by hand** follows the same rules. **Link Offer** and **Unlink Offer**, on the referral's [AWS Marketplace transactions](/cosell/cosell-ace-fields/#aws-marketplace-transactions) tab, work once the referral's review status is **Approved**, at **any** stage — including **Launched** and **Closed Lost**. (**Approved** is the AWS-native review status, not Fours' unified status — see [Status & Stage](/cosell/cosell-status/) for the mapping.) The offer you link must belong to the AWS account your ACE integration is connected as, or carry no seller account of its own; an offer from another of your AWS Marketplace accounts is refused with a message naming both accounts. ::: ## Inbound Setting The Inbound Sync section defines the data flow **from your Cloud Partners to the CRM platform**, indicating that information is sent to the CRM system. Fours continuously applies updates and changes made by Cloud Partners to the corresponding records in your CRM. In the Inbound Sync configuration, each tab (such as Opportunity, Opportunity(Salesforce)/Deals(HubSpot), Account(Salesforce)/Companies(HubSpot), and Contacts) represents an object that will be synchronized. When a new referral is received from a Cloud Partner, Fours automatically maps and writes the referral data into the corresponding fields of these CRM objects based on your field mapping configuration. The Settings tab defines general sync behaviors, while all other tabs specify which CRM objects and fields the inbound data should be populated into. :::note Inbound sync runs for AWS, Azure, and GCP. See [Referral Syncing](/cosell/cosell-syncing/) for how often each partner's inbound sync runs. ::: ### Objects Tab

Tab names such as Opportunity (Salesforce) / Deals (HubSpot), Account (Salesforce) / Companies (HubSpot), Contacts, and more.

Setting in these tabs is to control how fields are pre-filled when you create a new referral share from Cloud Partners to CRM. If the auto-share referrals setting is turned on, this configuration will be applied to all automatically shared referrals. In the configuration table, the title of each row represents the field name in the CRM. You can use the search dropdown to select which Cloud Partner's field should be mapped to it. You can add or remove CRM fields to customize your own mapping rules. Use **Picklist Value Mapping** (if available) or **Expression Mode** to define complex data-mapping rules, including conditional logic, value conversions, and cross-field mappings. See the related section for detailed documentation and examples. #### Mapped values your CRM does not accept A CRM dropdown field accepts only its own options. While you edit an inbound mapping into Salesforce or HubSpot, for AWS, Azure, or GCP, Fours checks what each field would receive against your CRM's own field definitions and lists the values it will refuse in a **These values may not reach your CRM** panel. Each line names the field, the value, and the options the field accepts. It flags: - a source field mapped straight to a dropdown with no picklist mapping, so the partner's values are sent as-is; - a picklist mapping, a **Default Value**, or an **Expression Mode** expression with no template fields, that sends a value the field doesn't have. The panel is advisory, and you can still save. The usual fix is a [Picklist Value Mapping](#picklist-value-mapping) that translates the partner's values into the field's own. When an inbound sync then writes a referral into your CRM, a value the field can't accept is **left out of that write** rather than sent. The other mapped fields still land, where before one refused value could void a whole HubSpot write and leave every mapped field on the deal empty. Nothing already on the record is cleared. ```d2 direction: right value: "Mapped value\nfor a CRM field" check: "Does the field\naccept it?" { shape: diamond } write: "Written with the\nother mapped fields" omit: "Left out of this write\nother fields still land\nnothing is cleared" value -> check check -> write: "yes" check -> omit: "no" ``` | CRM | What Fours checks | What it doesn't | | --- | --- | --- | | **HubSpot** | Dropdown properties, against the options the property lists. A date property also receives a proper date rather than a raw timestamp. | Properties whose options HubSpot doesn't list, including **Deal Stage**, whose values belong to the pipeline. | | **Salesforce** | Restricted picklists. An inactive picklist value counts as not accepted. | Unrestricted picklists and text fields, which accept any value. | Values are matched exactly, with no case folding and no label matching, so translate them with a picklist mapping rather than relying on a near match. #### Salesforce Only – Add Objects > Adding a Salesforce object to the sync configuration When syncing with Salesforce, you can use this field to search for and add more objects to sync, once the related field mappings have been completed. Mapping to custom Salesforce objects is supported, but typically requires a Solutions Engineering request to scope the trigger logic and data flow correctly. This isn't available for HubSpot. ### Setting #### Auto-Accept Referrals Automatically accept inbound referrals from **AWS** and **Azure**. Referrals from Google Cloud are never auto-accepted. Auto-accept is switched on per cloud, on the integration rather than on this page: - **AWS** — turn on **Auto-Accept Referrals** when you edit the AWS ACE integration. Fours accepts an engagement invitation that is still **Pending** and has not expired. - **Azure** — turn on **Auto-Accept Referrals** when you edit the Azure Marketplace integration; the switch appears once **Enable Cosell** is on. Fours accepts a referral whose substatus is **Pending**. Each accept Fours attempts runs as its own workflow, listed under **Metrics → Logs** with the **Auto-accept** workflow type — see [Inbound Sync](/cosell/cosell-syncing/). On AWS the accept goes to ACE, which completes it on its side; on Azure it starts an outbound sync that carries it to Microsoft. ```d2 direction: right ref: "Inbound referral\nfrom AWS or Azure" check: "Pending, and\nAuto-Accept on?" { shape: diamond } manual: "You accept or\nreject it yourself" run: "Auto-accept run\n(Metrics → Logs)" aws: "AWS: accept\nsent to ACE" azure: "Azure: outbound sync\nto Microsoft" col: "Auto Accepted ✓\n(when it was sent)" ref -> check check -> manual: "no" check -> run: "yes" run -> aws run -> azure aws -> col azure -> col ``` To see which referrals Fours accepted, add the **Auto Accepted** column from the **Columns** menu of the Cloud Partners referral table; it is hidden by default. A check marks a referral Fours auto-accepted, and hovering it shows when the accept was sent. The check means the accept was sent — the cloud partner confirms it separately. Referrals you accept yourself never get a check, and on Azure an accept gets one only when it started a new sync to Microsoft: if a sync for the referral is already running, or your referral approval holds it, the accept is saved and the run completes without a check. #### Auto-Delete Referrals Enable Auto-Delete to automatically remove referrals that are rejected by **YOU (the ISV)**. When this option is turned on, once a referral is rejected, Fours will delete the corresponding **opportunity/deal** in your CRM and soft-delete the referral in the Fours Console. By default, soft-deleted referrals are **hidden from view** and **cannot be reused or referenced**. #### Auto-Sync Contacts Automatically synchronize contact information received from Cloud Partners to your CRM system. When enabled, contact details from inbound referrals (such as name, title, email, or phone number) are added or updated in your CRM’s contact records. Set **SyncMode** to "None" if you prefer to manage contacts manually. :::note For AWS, contact information typically syncs 10–30 minutes after a referral is accepted, not immediately. ::: ## CRM-Specific Setup The mapping methods and automations above apply to every connected CRM. A few setup steps are specific to each one. ### Salesforce Before configuring, confirm the Fours Salesforce package is installed and the Integration User is connected in your Fours Console: - **Integration User access**: Salesforce must be connected to Fours with the **Suger Integrator** permission set, and that user needs **Read** and **Edit** access to any Salesforce fields you intend to map. - **Widget installation**: The Suger Quick Panel must be added to your **Opportunity** page layout. When defining outbound field mappings, pay special attention to these Salesforce fields: - **Owner attribution**: Map `Owner.Email` so the correct sales rep is credited in the AWS/Azure/GCP portal. - **Customer website**: `Account.Website` is used as the primary key for account matching and Auto-Enrichment. - **Customer location**: AWS and Azure require valid country codes. Make sure `Billing.Country` is mapped correctly. - **Close date**: `CloseDate` — partners reject dates in the past or more than two years in the future. - **ACE IDs**: The `Partner CRM Unique ID` (Opportunity ID) is usually mapped by default and doesn't require manual configuration. - **Project details**: `Description` maps to "Customer Problem" — the primary field partner managers read. **Fields on related records.** In the Salesforce field picker, a lookup field — such as the opportunity's account or its primary campaign source — has an arrow. Open it to list the fields of the record it points to, and pick one of those to map a value such as `Account.Website` or `Campaign.Name`; the picker shows each field's path under its name. A lookup opens when it points to a custom or external object, or to one of these standard objects: Account, Campaign, Case, Contact, Content Document, Content Version, Contract, Lead, Opportunity, Opportunity Contact Role, Opportunity Product, Order, Price Book, Quote, Record Type, or User. A lookup to any other object, such as Opportunity History or Product, lists no fields. ### HubSpot Before configuring, confirm HubSpot is connected and verified under **Settings > Integrations**, and that the Suger App is added to your HubSpot Deal "Default View" (see [Set up the Fours App in HubSpot](/hubspot-app/hubspot-app-configuration/)). To let Fours record which cloud partners each deal has been shared with, set up a **Referral State** property. The steps below are the short version; [HubSpot → Referral State](/integrations/hubspot/#referral-state) has the full setup and the deal filters it enables. **In HubSpot — create a property group (if needed):** 1. Go to **Settings**, then **Properties** under **Data Management**. 2. Select **Deal properties** from the object dropdown, then open the **Groups** tab. 3. Reuse an existing group, or click **New Group** and create one. ![HubSpot Deal properties Groups tab](images/configure-co-sell-settings-for-hubspot-1.png) **In HubSpot — create the property:** 1. On the **Properties** tab, click **New Property**. 2. Confirm the object type is **Deal**, and choose your group. 3. Label the property "Referral State" (or any name you prefer). 4. Set the field type to **Multiple Checkboxes**. 5. Add at least three options whose internal values are exactly **AWS**, **Azure**, and **GCP**, including case — **Verify** checks for those three values. 6. Click **Create**. **In the Fours Console — register the property:** 1. Go to [**Settings > Integrations**](https://console.suger.io/settings?tab=integrations) **> HubSpot card**, and click **Edit**. 2. In the **Advanced** section, find **Deal Referral State Property**. 3. Enter the property's **Label** (not its Internal Name). If it isn't listed, click the refresh icon to reload it. 4. Click **Verify**, then **Save**. ![Deal Referral State Property field in the HubSpot integration Advanced settings](images/configure-co-sell-settings-for-hubspot-2.png) 5. Back on the HubSpot integration, click **Sync** to populate the referral state on existing deals. This can take several minutes. :::tip Once populated, you can filter Co-Sell deals by Referral State: operator **IS NULL** finds deals never shared with a partner; **IS IN** + selected partners finds deals already shared. ::: **Customer contact.** The default outbound mappings for AWS, Azure, and GCP fill the referral's customer contact from the deal's contact properties (`contacts.firstname`, `contacts.lastname`, `contacts.email`, …). A deal can carry several contacts, so Fours reads one. A deal with one associated company, or none, uses its first contact. When the deal has two or more companies, Fours reads the first contact on the deal that is associated with the deal's primary company; if none of the deal's contacts is, Fours leaves the customer contact empty — associate the customer's contact with the deal's primary company in HubSpot to fill it. See [Which deal contact becomes the customer contact](/integrations/hubspot/#which-deal-contact-becomes-the-customer-contact). ## Test Field Mapping Use the Test button for field mapping validation button to verify whether your field mapping configuration works as expected. **Test Mapping is available on the Outbound field-mapping step only.** There is no equivalent test on the Inbound tabs, though they do flag mapped values your CRM will refuse while you edit — see [Mapped values your CRM does not accept](#mapped-values-your-crm-does-not-accept). To check anything else about inbound behaviour, watch what an actual inbound referral writes into your CRM. **Test Mapping** opens the **Test mapping** dialog, which shows the referral the cloud partner would receive for one of your CRM records — AWS, Microsoft, Google Cloud, or a Fours partner (`SUGER`). Test Mapping is restricted to organization admins, because it runs live CRM queries and your configuration's code; anyone else sees a message saying so. 1. Pick a record under **Test with**. The dialog opens on your most recent record, and the list holds your latest ones; type to search it. With Salesforce, the search also queries Salesforce by name, so you can reach older opportunities. 2. Fours reads the record from your CRM, applies your current mapping, and checks the result the way the partner would. A mapping with **AI** fields can take several tens of seconds. 3. Read the result. **Preview** shows it as the partner's own referral form, one section at a time; **JSON** switches to the raw source and target data. A summary line at the top counts what needs fixing, for example *2 would be rejected unless auto-fixed · 1 required and empty*, or reads *Nothing would be rejected or dropped.* The section list on the left shows each section's own count. Under every field the preview names any problem, then where the value came from — a CRM field (*from …*), a *Default value*, *Generated by AI*, or a *formula*, with *value mapping* added when a picklist mapping applies. An empty value shows as —. | Problem line | Meaning | | --- | --- | | **Rejected unless auto-fixed** | The partner's validator rejects the value as mapped | | **Dropped** | The partner's validator would silently remove or cut the value, so it doesn't arrive as mapped | | **Reformatted** | The value is rewritten into an equivalent form — nothing is lost | | **Not mapped** | The mapping for this field failed; the line gives the reason | | **Required** | The partner requires the field, and it is empty | Problems that belong to no single field, such as a failure of the whole configuration, appear under **Other problems**. The preview is stricter than a real share. When you share, Fours tries to fix rejected values first — AWS and GCP referrals get an automatic AI fix, and Microsoft referrals have some invalid values corrected — so a field marked **Rejected unless auto-fixed** may still go through. Fix the mapping anyway rather than rely on the repair. A Fours partner (`SUGER`) configuration has no partner validator, so its preview reports only mapping failures and empty required fields. :::tip The share page is your sandbox before finalizing any mapping — if data looks wrong or empty there, it'll be wrong in the partner portal. Open any opportunity and click **Share** to catch problems before they reach the partner. See [Outbound Referral](/cosell/cosell-outbound/). ::: ## Picklist Value Mapping > Stage Name picklist mapping from Salesforce to Microsoft stages Some fields support Picklist Value Mapping, which allows you to define value correspondences between your CRM and Cloud Partner Platform. This feature is used to create **simple one-to-one mappings** between different picklist values. For example, the image above shows a Stage Name mapping where Salesforce stages are mapped to their corresponding Microsoft stages. In other fields, you may need to enter values manually instead of selecting them from dropdown lists. Users can add or remove mapping rows as needed to customize how each value aligns between the CRM and Cloud Partner. **Where to find it.** On an outbound row, picklist value mapping is a recipe inside **Formula**: click **Formula**, stay on **Build**, and choose **Picklist**. Pick the CRM field under **Map values from**, then map each of its values. The recipe is offered only when the partner field has a fixed list of values. On an inbound row, use the picklist button next to the field instead (its tooltip reads **Use Picklist**). ### Prevent a duplicate Closed Won A stage-mapping row can carry an optional **Validation rule** that runs *before* the stage transition is applied. Today one rule is offered: **Prevent duplicate Closed Won**. It guards against a deal being counted as won twice — once in one cloud's co-sell portal, and again in another — when the same CRM opportunity has already transacted elsewhere. **Where to set it.** In the outbound configuration for **AWS**, open the stage picklist mapping (**Formula** › **Picklist** on the stage field) and find the row whose **target** stage is `Launched` (AWS's closed-won equivalent). A **Validation rule** dropdown appears next to that row, defaulting to **None**. Set it to **Prevent duplicate Closed Won**. The dropdown is offered only on that row: it does not appear on other stage rows, on inbound configurations, or on clouds that do not support the rule. **What it does.** When a referral is about to move into the guarded stage, Fours looks for an **accepted offer in a different cloud** — AWS, Azure, or GCP — attached to the *same* CRM record as this referral. If it finds one, the stage update is **skipped**. ```d2 direction: down update: "Referral update arrives\nstage moving to the guarded stage" configured: "Validation rule set on\nthis stage-mapping row?" { shape: diamond } linked: "Referral linked to a\nCRM opportunity / deal?" { shape: diamond } lookup: "Look for an ACCEPTED offer\nin another cloud (AWS · Azure · GCP)\non the same CRM record" found: "Conflict found?" { shape: diamond } apply: "Stage update applied\nthen synced outbound to the partner" skip: "Update SKIPPED SILENTLY\nnot saved · not synced outbound\nno error returned" banner: "Cross Cloud Conflict banner\nshown on the referral" update -> configured configured -> apply: "no" configured -> linked: "yes" linked -> apply: "no — rule cannot run" linked -> lookup: "yes" lookup -> found found -> apply: "no" found -> skip: "yes" skip -> banner ``` Three things are worth knowing about that skip: - **It is silent.** Nothing is persisted, no outbound sync runs, and **no error is returned** — the request looks like it succeeded. The referral simply stays in its previous stage. - **It needs a CRM link.** A referral not linked to a Salesforce opportunity, HubSpot deal, or Dynamics 365 opportunity has no record to match on, so the rule cannot run and the update proceeds normally. - **It is configuration-only.** There is no row action or picklist entry for it in the referral list — you enable it here and observe it there. Because the skip is silent, the referral detail page raises a **Cross Cloud Conflict** banner naming the conflicting offer. That banner is how you find out. See [Status & Stage](/cosell/cosell-status/#cross-cloud-conflict) for how to read and resolve it. ## Expression Mode Expression Mode lets you build advanced field-mapping logic—such as conditional rules, value transforms, fallbacks, and simple calculations—when syncing data between your CRM and Cloud Partner. ### How to enable On an outbound row, click **Formula** to the right of the field. The formula editor opens with two tabs: - **Build** — put the formula together from a recipe, without writing a template. See [Build a formula from a recipe](#build-a-formula-from-a-recipe). - **Code** — write the Go template yourself, as described on the rest of this section. **Insert Salesforce field** (named for your CRM) adds a field reference for you. On an inbound row the button is labelled **Expression** and opens the template editor directly. ### Build a formula from a recipe On the **Build** tab, choose a recipe: | Recipe | What it does | | --- | --- | | **Picklist** | Translates a CRM field's values into the partner's values — see [Picklist Value Mapping](#picklist-value-mapping). Offered only on fields with a fixed list of values. | | **Transform a field** | **Take** a CRM field *as it is*, *multiplied by*, *divided by*, *plus*, or *minus* a number, or *with text before* or *with text after* it. **Add field** adds another part, and **Join with** sets what goes between the parts: *a space*, *a comma*, *a dash*, or *nothing*. | | **IF / THEN rules** | **IF** a field *equals*, *does not equal*, *contains*, *is greater than*, *is less than*, or *is not empty*, **Then send** a value. **Add rule** adds an **ELSE IF**; **Otherwise send** sets the value when no rule matches. | **Transform a field** and **IF / THEN rules** produce the same kind of Go template you would write on **Code**. If a field's formula was written by hand, **Build** starts fresh, and saving from there replaces the original — switch to **Code** to keep it. When a field has both a value mapping and a formula, the value comes from the formula and the mapping is applied to its output. ### What you can do - Conditional mapping (if/else) - Default/fallback values for empty fields - String/number transforms and simple calculations - Cross-field lookups (read one field to populate another) #### Example — set a default country when empty The snippet below writes the company country if present; otherwise it uses USA. ``` {{- if .companies.country -}} {{ .companies.country }} {{- else -}} USA {{- end -}} ``` #### Syntax Expression Mode uses Go Templates (text/template). **Reference:** https://pkg.go.dev/text/template #### Validation & troubleshooting - Invalid template syntax will cause the sync to fail for that field. - Use **Test Mapping** to verify output before saving (see [Test Field Mapping](#test-field-mapping)). - Ensure referenced paths (e.g., .companies.country) exist in your inbound/outbound payload. :::tip Expression Mode applies per field. Other fields continue to use their own mapping or expressions independently. ::: ## Sync Timing & History Once a referral is shared or accepted, Fours keeps it in sync across your CRM, Fours, and the cloud partner for the life of the deal. - **Outbound syncs** (CRM → partner) run roughly every 6 hours. - **Inbound syncs** (partner → CRM) run roughly every 3 hours, with new inbound referrals usually detected within minutes. - You can trigger either sync manually at any time — actions taken directly in the Fours widget (such as sharing a new referral) run immediately rather than waiting on the schedule. Referrals in an inactive state (Draft, Rejected, Expired, or Deleted) are not synced in either direction. Closed referrals (Closed Won / Closed Lost / Closed Error) are no longer pushed **outbound**, but they still receive **inbound** updates from the cloud partner. If the same field is updated in both your CRM and the partner portal between sync cycles, the most recent change wins — turn off a field's Sync Fields toggle if it shouldn't sync at all. Click the **History** button in the **Cosell Configs** header (**Co-Sell › Settings › Configs**) for a timestamped log of configuration changes, including who changed the mapping logic and when. You can also review sync runs under Metrics > Logs, filtering Workflow Type to Sync. ## Troubleshooting Common Issues | Issue | Cause | Resolution | | --- | --- | --- | | Engagement Scores missing in CRM | Co-sell Intelligence has not been enabled for your org, or your org exceeded its retrieval quota | Contact [support@suger.io](mailto:support@suger.io) to have the signals enabled, then check usage in the **Quotas** tab | | Can't create a second config for the same partner | Only one active configuration is allowed per hyperscaler | Edit the existing config instead of creating a new one, or deactivate it first | | "This configuration was modified by another user…" when saving | Two people had the same configuration open and the other person saved first | Reload the configuration to pick up their change, reapply your edit, and save again. Agree who owns a configuration before a joint editing session | | "This field is already synced by another filler" | Two field fillers both claim sync on the same partner field — a field can be claimed by only one | Remove the duplicate claim: decide which filler should own the field and turn sync off on the other | | Field empty on the share page | The mapping points to a CRM field that's blank on that record | Populate the missing data in your CRM and reload the share page, or add a Default Value in the configuration | | Field highlighted in red on the share page | Data validation failure (e.g., text in a date field, invalid country code) | Use Expression Mode to reformat the data, or switch to a source field matching the partner's required data type | | "unsupported partner: X" | Incorrect capitalization in Expression Mode or Apex actions | Use ALL CAPS for partner references: `AWS`, `AZURE`, `GCP`. In HubSpot, the checkbox option values must also match character-for-character | | Referral status not updating in HubSpot | The Referral State property Label in Fours doesn't match the property in HubSpot | Re-enter the property's Label (not Internal Name) under **Integrations > HubSpot > Advanced > Deal Referral State Property** | | Auto-Share failed to trigger | Invalid SOQL predicate (Salesforce) or incorrect ILS Segment ID (HubSpot) | Salesforce: click **Preview matches** to test the criteria, use single quotes for strings. HubSpot: verify the ID matches the ILS Segment ID in Segment details | | Sync failed after a stage change | A CRM stage was moved to a value not defined in Picklist Mapping | Locate the Stage field in the configuration and map every active CRM picklist value | | Enrichment didn't fill fields | Missing a valid company website or domain on the CRM record | Populate the Website field on the Account/Company record — Fours uses it as the enrichment primary key | | A change hasn't appeared yet | Waiting on the scheduled sync | Outbound runs roughly every 6 hours, inbound roughly every 3 hours. Trigger a manual sync if you need it sooner | | Referral shows "Create Failed" / "Update Failed" | Sync error | Hover over the status in the referral list, or open the referral's detail page, for the specific partner error message | | After an inbound sync, one mapped field stays empty on the CRM record while the others fill | The partner's value isn't one the CRM field accepts, so Fours left it out of the write | Check the mapping's **These values may not reach your CRM** panel, then add a [picklist mapping](#picklist-value-mapping) that translates the value. See [Mapped values your CRM does not accept](#mapped-values-your-crm-does-not-accept) | | "Couldn't load HubSpot fields" or "Couldn't load Salesforce fields" on an AWS configuration | Fours could not read your CRM's field list — usually the CRM connection needs to be reauthorized | Reauthorize the CRM under **Settings > Integrations**, then reopen the configuration. Until then the rest of the mapping still shows, but the CRM field pickers are empty | | "Couldn't load this configuration" or "Couldn't load this field mapping", and **Save** is disabled | The saved mapping didn't load, so the form on screen isn't your real mapping | Reload the page. **Save** stays disabled so an empty form can't overwrite the mapping you saved | | No leads arrive from lead enrichment | Automation is off, the sync filter matches nothing, the mapping predates the Account source, or the matching Accounts can't be submitted | Check the readiness panel and **Validate** in the lead-enrichment mapping, then **Metrics > Logs**. See [Create Leads from Salesforce Accounts](/cosell/cosell-leads/#create-leads-from-salesforce-accounts) | ## Frequently Asked Questions **Q: Why isn't the Engagement Score showing in my CRM?** Either Co-sell Intelligence has not been enabled for your organization, or your organization has exceeded its retrieval quota. Co-sell Intelligence signals are enabled by Fours, not by your team — contact [support@suger.io](mailto:support@suger.io) to have them switched on, and check your usage in the **Quotas** tab. **Q: A score shows in the Fours widget, so why is it empty in my report?** Check which score you are looking at. The **Suger Predicted Engagement Score** in the Fours widget is Fours' own prediction, calculated for display and stored against the customer's domain rather than on the referral — so it is blank in reports, list views, formula fields and automation. Only the partner's own score for that opportunity, shown on the referral as **Engagement Score**, is written to the record. A blank report column means AWS has not scored that opportunity yet. See [Co-sell Insights](/cosell/co-sell-insights/). **Q: How do I turn Co-sell Intelligence signals on or off myself?** You can't — the enable toggles are managed by Fours and are not exposed on your **Co-Sell › Settings** tab. Contact [support@suger.io](mailto:support@suger.io) with which cloud partners you want covered. **Q: What happens if I delete a Co-sell configuration?** Deletion is immediate and permanent. All associated mapping logic and access tokens are removed, with no way to recover it. **Q: How do I handle fields with different names in different CRMs?** Co-Sell configuration is unique per hyperscaler. You define the logic once for AWS pointing to Salesforce fields, and once for AWS pointing to HubSpot fields — full flexibility per CRM. **Q: Does Fours support currency conversion in Expression Mode?** Yes. Since some partners (like AWS) require revenue in specific currencies, you can write an expression that multiplies your CRM amount field by a conversion rate before it's sent to the partner. **Q: What happens if I move a deal to a CRM stage I haven't mapped?** The sync will fail for that update. Every active stage in your CRM should be mapped to a partner-approved value in Picklist Mapping. **Q: Can I map data from custom objects instead of standard Opportunity/Deal objects?** Mapping to custom Salesforce objects is supported, but typically requires a Solutions Engineering request to scope the trigger logic and data flow. This isn't available for HubSpot. **Q: Will Auto-Enrich overwrite data my sales reps have already entered?** No. Enrichment only populates fields that are currently empty. If a field already has data, Fours treats your CRM as the source of truth and skips it. **Q: Can I automate deal sharing for only a subset of my team?** Yes. Use Auto-Share criteria — the Builder or Advanced (SOQL) for Salesforce, Segments for HubSpot — to limit automation to specific owners, regions, or product lines. Use **Preview matches** (Salesforce) to verify which records currently match before enabling it. **Q: Why does a referral status show as "Expired"?** A referral enters Expired when it isn't approved or rejected within the partner's time limit. This applies to AWS and Azure; GCP has no documented Expired state. **Q: Where can I see why a referral failed to sync?** Hover over a **Create Failed** or **Update Failed** status in the referral list, or open the referral's detail page, for the specific error message from the cloud partner. Some failures leave the status unchanged and put a red **!** on the status tag instead; hover over it for the reason. See [Failures that don't change the status](/cosell/cosell-status/#failures-that-dont-change-the-status). **Q: Do Fours roles (Admin, Editor, Viewer) inherit from Salesforce or HubSpot?** No. Fours roles are console-specific and don't inherit from CRM profiles or roles. Manage Fours permissions under **Settings > Users & Roles**. :::info For the unified Fours Status lifecycle and how it maps to each partner's native statuses and stages, see [Status & Stage](/cosell/cosell-status/). ::: --- Source: https://doc.fours.com/cosell/cosell-status/ # Status & Stage Co-Sell Referral Status & Stage Guide --- Managing referrals across different cloud marketplaces can be complex because AWS, Azure, and GCP all use different terminology for their statuses and stages. Fours unifies these into a single, standardized **Fours Status** to help you track your deals easily without needing to memorize specific definitions for every cloud provider. This guide explains what each Fours status means and how it maps to the specific status or stage in AWS, Azure, and Google Cloud. The co-sell status as it appears in the Console UI, Salesforce, and HubSpot, with a referral pending acceptance in each ## Status Overview & Mappings The table below shows the correspondence between the unified Fours Status and the native Partner Status/Stage. | Fours Status | Explanation | AWS Mapping | Azure Mapping | GCP Mapping | |--------------------|---------------------------------------------------------------------------------------------------------------------|------------------------------------------|----------------------------|---------------------| | **Draft** | The referral is saved as a draft in Fours and has not been submitted to the cloud partner yet. | (Not yet synced) | (Not yet synced) | (Not yet synced) | | **Pending Create** | The referral is currently being processed by Fours and will be created on the partner portal shortly. | Pending Create | (N/A) | (N/A) | | **Create Failed** | The submission failed. You can hover over the status icon to see the specific error message. | (Error) | (Error) | (Error) | | **Update Failed** | A later update to an existing referral failed to reach the cloud partner. The referral still exists — hover over the status icon to see the specific error message. | (Error) | (Error) | (Error) | | **In Review** | Successfully submitted. Waiting for the cloud partner to review. | Status: Submitted, In Review | SubStatus: Pending (Outbound) | State: SUBMITTED | | **Pending Acceptance** | Action Required: You received an inbound referral. Please accept or decline it to proceed. | Status: Received (Engagement Invitation) | SubStatus: Received (Inbound) | (N/A) | | **Action Required** | Action Required: The cloud partner requires updates. Please modify the referral based on feedback and submit again. | Status: Action Required | (N/A) | (N/A) | | **Rejected** | The referral was rejected by the cloud partner. | Status: Rejected | SubStatus: Declined | State: NOT_ACCEPTED | | **Expired** | The referral expired because it was not approved or rejected within the time limit. | Status: Expired | Status: Expired | (N/A) | | **Active** | The referral is active. It has been accepted by the cloud partner or created as a self-led referral. | Status: Approved | Status: Active & SubStatus: Accepted | State: ACCEPTED | | **Closed Won** | The referral has been successfully closed as Won. | Stage: Launched | SubStatus: Won | Stage: MIGRATION_IMPL | | **Closed Lost** | The referral has been closed as Lost. | Stage: Closed Lost | SubStatus: Lost | Stage: CLOSED_LOST | | **Closed Error** | The referral was closed by the cloud partner due to a validation or system error. | (N/A) | SubStatus: Error | Stage: CLOSED_ADMIN | ## Azure-only Columns Two extra columns appear on the **Azure** tab of the referral list. They are shown by default, and they are removed automatically when you switch to a non-Azure tab — AWS and GCP have no equivalent, so there is nothing to show. ### Microsoft Status **Microsoft Status** is Microsoft's own copy of the referral state, shown next to the unified Fours Status. Use it when you need to reconcile against what Partner Center displays rather than what Fours has normalized. Microsoft expresses the state as a **Status** plus a **Substatus**: | Part | Values | | --- | --- | | **Status** | `New` · `Active` · `Closed` · `None` | | **Substatus** | `None` · `Pending` · `Received` · `Accepted` · `Won` · `Lost` · `Declined` · `Expired` · `Error` | The pair is what carries the meaning — for example, `Active` + `Accepted` is a referral Microsoft has taken on, while `Closed` + `Won` is a referral Microsoft considers won. The Fours Status column above collapses these pairs into a single value. ### Co-sell Type **Co-sell Type** records how the deal is being run with Microsoft: | Value | Meaning | | --- | --- | | **Co-sell** | Both you and Microsoft are actively working the deal together. | | **Partner-led** | You lead the deal; Microsoft has visibility but is not selling alongside you. | | **Private** | The referral is kept private to your organization. | ## Understanding Key Features ### 1. Unified View Instead of juggling AWS "Stages," Azure "Sub-statuses," and GCP "States," you can rely on the **Fours Status** column to know exactly where a deal stands in the lifecycle. Each status carries an in-product tooltip. Hover the status on any referral to read the same explanation the table above gives, without leaving the list. ### 2. Error Troubleshooting If a referral enters the **Create Failed** or **Update Failed** state: Referral list showing Create Failed status with error hover **Hover:** You can hover your mouse over the status in the list view to see a card containing the specific error message explaining why it failed. **Detail Page:** The error message is also visible directly on the referral detail page. #### Failures that don't change the status Not every failure shows up as **Create Failed** or **Update Failed**. Some leave the referral's status exactly as it was (**Active**, for example) and put a red **!** on the status tag instead: - **Hover** the tag. Instead of the usual status explanation, the hover card shows the reason, under an **Update Failed** label. - **Open the referral.** On an AWS, Azure, or GCP referral, a banner at the top of the detail page reads `Update Failed: `. - **Find every affected referral.** With AWS, Azure, or GCP selected in the referral list, add the filter **Update Status** = `FAILED`. The mark clears on its own the next time the same action succeeds, so there is nothing to dismiss. Situations that produce the mark include: | What failed | The reason shown | What to do | | --- | --- | --- | | A CRM change failed Fours' AWS update check, so it never reached AWS | Starts with `CRM sync rejected:` | See [Referral Syncing → Troubleshooting](/cosell/cosell-syncing/#troubleshooting) | | Accepting or declining an AWS engagement invitation | The error AWS returned | See [Inbound Referral](/cosell/cosell-inbound/#if-accepting-or-declining-an-aws-invitation-fails) | | A CRM stage mapped to Won could not close a Fours co-sell | What blocked the close | See [CRM Closed Won didn't close the co-sell](#crm-closed-won-didnt-close-the-co-sell) below | #### Cross Cloud Conflict Not every blocked change shows up as a failure. If you enabled the [**Prevent duplicate Closed Won** validation rule](/cosell/cosell-configuration/#prevent-a-duplicate-closed-won), Fours checks — before moving a referral into the guarded stage — whether the same CRM opportunity has **already transacted in a different cloud**. When it has, the stage change is skipped rather than rejected: nothing is saved, nothing is pushed to the partner, and no error is returned. Because that skip is silent, the referral detail page raises a dismissible yellow **Cross Cloud Conflict** alert instead. It tells you: - which automatic action was skipped, and the stage it would have moved to; - which cloud the deal appears to have already transacted in; - the CRM record value that matched, and a link to the conflicting offer. **What to do:** open the linked offer and confirm which cloud the deal genuinely closed in. If this referral should close too, move the stage in the partner portal directly, or turn the validation rule off for that stage mapping. Dismissing the alert only hides it — it does not apply the skipped change. #### CRM Closed Won didn't close the co-sell This applies to **Fours partner-to-partner** co-sells. When the CRM opportunity linked to your copy of the co-sell moves to a stage mapped to **Won** in your [stage mapping](/cosell/cosell-configuration/#picklist-value-mapping), Fours closes the co-sell as Won for you. Only the seller's copy (the one linked to your CRM) is closed this way. The automatic close runs the same checks as the **Close Won** gate. If one of them fails, the co-sell stays open, and the right-hand panel of its detail page shows an amber **Action Required** card headed **CRM opportunity closed won**, with the reason. The most common reasons: | Reason on the card | What to do | | --- | --- | | The co-sell hasn't been accepted yet | Only an **Active** co-sell can close as Won, so the co-sell has to be accepted first. | | The final deal value is missing | Add a deal value greater than 0. | | The deal value currency is not set | Set the currency. | | A partner's commission terms are still incomplete | Finish that partner's commission terms. | If you are the seller and the co-sell is **Active**, the card also offers **Complete & Close Won**. It opens the [Close Won gate](/cosell/cosell-outbound/#board-view), where you supply what is missing and close the deal. The card disappears once the co-sell is closed as Won. ```d2 direction: down crm: "CRM opportunity moves to\na stage mapped to Won" sync: "Fours CRM sync\n(seller's copy)" check: "Close Won checks pass?" { shape: diamond } won: "Co-sell closed as Won" card: "Co-sell stays open\nAction Required card names the reason" gate: "Complete & Close Won\n(seller, Active co-sell)" crm -> sync -> check check -> won: "yes" check -> card: "no" card -> gate: "fix the cause" gate -> won ``` For the rest of the deal page, see [Track and Respond to Deals](/prm/track-and-respond-to-deals/). ### 3. Inbound vs. Outbound Logic **In Review:** Generally applies to **Outbound** referrals (deals you sent to the cloud partner) that are waiting for their approval. **Pending Acceptance:** Applies to **Inbound** referrals (opportunities the cloud partner sent to you) that require your acceptance. --- Source: https://doc.fours.com/cosell/cosell-outbound/ # Outbound Referral Share opportunities from your CRM with partners --- ## Overview With your co-sell configurations, sharing with partners can be as easy as a few mouse clicks. ## Outbox Outbox is the place to show your CRM opportunities that are ready to be sent to partners. Without any configuration, this tab lists all your CRM opportunities. You can click the filter button to specify various filters to narrow down the scope: > Filter options for narrowing down Outbox opportunities You can also use the search box on the top right: > Search box for Outbox opportunities ## Share an Opportunity Sharing happens on its own **full page**, not in a pop-up dialog. The page has its own URL, so you can bookmark a share in progress, reload it, or send the link to a colleague. Its header reads **Share to {cloud} co-sell referral** — for example, *Share to AWS co-sell referral*. Below is an example where we share a Salesforce opportunity with AWS. 1. Find an opportunity from the Outbox. 2. Click on the opportunity name (in **teal** color) which navigates to the detail page. 3. Click the **Share** button on the top right. Fours opens the share page. 4. Work through the **stepper** at the top of the page. Each step groups a related set of fields; fill in the required fields, and any optional fields you want to send. 5. If all validation passed, the **Submit** button will be clickable. Click on it. 6. Fours sends this to AWS. This process usually takes ~5 seconds but sometimes it takes longer. 7. The shared opportunity will be moved to the "In Sync" tab. > Shared opportunity listed in the In Sync tab 8. You can click on it to check the details. You should see the "APN CRM Unique Identifier" in the "Destination" section on the bottom. > APN CRM Unique Identifier shown in the Destination section :::note Because the share page is a page and not a dialog, navigating away — clicking a link, using the browser Back button, or closing the tab — triggers an **unsaved-changes guard**. Confirm to leave and discard what you have filled in, or cancel to stay on the page. ::: ### Duplicate title advisory When you submit, Fours checks whether the same partner already has a **still-open** referral with a matching title. Matching ignores letter case and surrounding whitespace, so "Acme Corp — Migration" and "acme corp — migration " count as the same title. If it finds one, Fours shows you the matching referrals so you can decide whether you are about to create a duplicate. :::info This is **advisory only — it never blocks the share.** Two referrals can legitimately carry the same title, for example two phases of the same programme with the same customer. Read the list, then submit anyway if the new referral is genuinely distinct. ::: ## Invite other AWS partners On an AWS referral you can invite other AWS partners — a reseller or a services partner, for example — to work the opportunity with you. Fours sends each one an AWS engagement invitation through AWS Partner Central. You can invite only partners your AWS Partner Central account is connected to; Fours refreshes that list of partner connections from AWS every 6 hours. You can invite partners in two places: - **While you share** — the AWS share page ends with a **Partner Collaboration** step. - **After the referral exists** — open the AWS referral and click **Share With Partners**. ### Invite partners while you share The **Partner Collaboration** step is optional. Fill it in to invite partners in the same submission: | Field | What to enter | | --- | --- | | **Partner Connection Name** | Type to search your connected partners by company name or AWS account ID, and pick one or more. Each option shows the company name with **AWS Account:** and its account ID underneath. | | **Partner Engagement Type** | One or more of: Distributor, Reseller, Hardware Partner, Managed Service Provider, Software Partner, Services Partner, Training Partner | | **Comments to share with the partner** | Up to 255 characters | Once you pick a partner, an engagement type and the comments become required, and **Submit** stays disabled until both are filled in. Fours sends one invitation per selected partner, each with the same engagement types and comments. ### Invite partners to an existing referral On the AWS referral's page, click **Share With Partners**. The **Share with Partner** dialog sends one invitation at a time: - **Sender** — your **Email** (required), plus an optional **First Name**, **Last Name**, **Business Title**, and **Phone Number**. - **Partner** — the **Partner Connection Name**, at least one **Partner Engagement Type**, and the **Comments to share with the partner** (up to 255 characters), all required. **Share With Partners** is disabled when any of these is true: - The referral already has 10 outbound invitations. - AWS has not yet given the referral an opportunity ID. - The referral's status is **Draft**, **Create Failed**, or **Deleted**. - Its stage is **Launched** or **Closed Lost**, or it has no stage yet. - It is an inbound referral still waiting for you to accept it (**Pending Acceptance**). ### Track the invitations The AWS referral's **Invitations** tab lists every invitation sent on it: | Column | Shows | | --- | --- | | **Partner** | The partner connection's name, with its AWS account ID underneath — or the account ID alone when it matches none of your connections | | **Invite Time** | When the invitation was sent | | **Status** | The invitation's status at AWS | | **Invitation Id** | AWS's ID for the invitation | | **Sender(s)** | The company that sent it | | **Link to invitation** | Opens the invitation's page: **Overview**, **Customer Details**, **Project Details**, and **Partners** | Right after it sends an invitation, Fours reads every invitation on the referral back from AWS and stores the dates, sender, message, and customer and project details AWS returns. It does not poll for answers: when an invited partner accepts or rejects the invitation, AWS publishes a status-change event, and Fours reads that event through the Amazon EventBridge rule your [AWS Partner Central integration](/integrations/aws-partner-network-api/) set up, then updates **Status**. An invitation recorded before early October 2026 can show blank dates or no sender until another invitation is sent on that referral. ```d2 shape: sequence_diagram you: "You (Fours Console)" fours: Fours aws: "AWS Partner Central" partner: "Invited AWS partner" you -> fours: "Pick partners, engagement types, and comments" fours -> aws: "One engagement invitation per partner" aws -> partner: "Engagement invitation" fours -> aws: "Read every invitation on the referral back" aws -> fours: "Dates, sender, message, customer and project" { style.stroke-dash: 4 } fours -> you: "Listed on the Invitations tab" partner -> aws: "Accepts or rejects the invitation" aws -> fours: "Status-change event, read through EventBridge" { style.stroke-dash: 4 } fours -> you: "Invitation status updated" ``` ### Partner names Partner names come from AWS. Each time Fours syncs your partner connections, it asks AWS Partner Central for each partner's published company name. Where AWS returns none — for example, for a partner whose profile isn't published — the partner appears as **AWS Account** followed by its account ID until a later sync resolves it. A name that was resolved once is never replaced by the placeholder after a failed lookup. ## Re-submit a failed referral A referral that failed on the way to the partner does not have to be recreated from scratch. Open the referral's detail page and use the **Re-submit** action. **When Re-submit is available** | Situation | Re-submit? | | --- | --- | | Status is `CREATE_FAILED` | Yes | | AWS referral whose review status is still pending submission | Yes | | Any other status — the referral is healthy or already at the partner | No | If you reach the re-submit flow for a referral that does not qualify, Fours refuses it with: *"This referral cannot be re-submitted."* **What happens when you re-submit** 1. Open the failed referral's detail page. 2. Click **Re-submit**. Fours seeds the form from the payload it stored on the original attempt, so every value you entered the first time is still there. 3. Correct whatever the partner rejected — the error message on the referral tells you what to fix. 4. Click **Submit**. :::info Re-submitting **updates the failed referral in place**. It never creates a second record, so your list will not fill up with duplicates of the same opportunity no matter how many times you retry. ::: ## Board view For **Fours partner-to-partner** co-sell, the referrals table offers a **List / Board** toggle. It appears only when the partner filter is set to Fours alone — the board's columns are Fours' own deal stages, which do not describe an AWS, Azure or GCP referral. Your choice is remembered in the browser. The board has nine columns: the eight deal stages — **Pending**, **Active**, **In Discovery**, **Proposal Sent**, **Negotiating**, **On Hold**, **Won**, **Lost** — plus a board-only **Rejected** bucket. Each column header shows how many deals the column holds and, when those deals carry a value, their total — added up per currency, because values in different currencies are never combined. Hover the info icon beside either figure for its definition. When the board has loaded only the first of the deals that match your search and filters, both figures cover the loaded deals only and are marked `≥`. Drag a card to change its stage. Two columns accept no drops, and say so rather than appearing to: | Column | Why you cannot drop into it | | ------ | --------------------------- | | **Pending** | The pre-accept state. Dropping here would revert an accepted deal to pending acceptance and re-arm the accept decision. | | **Rejected** | Rejection is a **status, not a stage**. A rejected deal's stage freezes where it was; the bucket exists so a dead deal is not presented as live pipeline. | Two stages open a confirmation before the change is saved: - **Lost** — requires a closed-lost reason. - **Won** — opens the Close Won gate: deal value, visibility, and commission. The board offers exactly the transitions the deal page's **Change Stage** dropdown offers, from one shared list, so the two cannot drift apart. ## Bulk Share You can share multiple opportunities at the same time. This can be very efficient if your CRM data is in good quality (e.g., all postal codes are filled) and the field mappings & templates are well-configured. 1. Click the `Bulk Share` button to enter the selection mode. > Bulk Share selection mode for Outbox opportunities 2. Select those you want to share and click `Submit`. 3. A dialog will pop out showing the AWS opportunity we are about to submit. > Bulk share confirmation dialog for AWS opportunities You can click on any of them to check the details. 4. If all validation passed, you can click the `Submit` button. Otherwise you'll need to manually fill them. :::info **A bulk share is capped at 30 referrals per batch.** To share more than 30 opportunities, split them across several batches. ::: ### Running two bulk shares at once You can start a second bulk share while a first one is still processing. Previously the second batch could be dropped, or leave rows sitting in **Pending Create** indefinitely — that no longer happens. If a batch cannot be started, its referrals are marked `CREATE_FAILED` rather than left stranded, with the message: > Could not start the {partner} submission for this bulk share — please resubmit the referral Those rows behave like any other failed referral: open one and use [**Re-submit**](#re-submit-a-failed-referral) to push it through. ## Auto-Share Retries [Auto-share](/cosell/cosell-configuration/#auto-share-referrals) does not give up on a referral the partner rejected. A `CREATE_FAILED` referral re-enters the candidate list on the next auto-share run — roughly every 3 hours — and Fours updates the existing record rather than creating a duplicate. | | | | --- | --- | | **Retried automatically** | `CREATE_FAILED` | | **Never retried** | `UPDATE_FAILED`, `PENDING_CREATE`, `DRAFT` | | **Retry limit** | 16 attempts, roughly 48 hours | After 16 attempts the referral stops being retried and stays `CREATE_FAILED`. At that point the cause is almost always data the partner will keep rejecting — fix the underlying field and use [**Re-submit**](#re-submit-a-failed-referral) on the referral itself. ## Auto-Enrich Referrals Save time and improve data quality by automatically filling in missing company and contact information when sharing opportunities with cloud partners. The auto enrichment feature helps ensure your referrals have complete information, increasing the chances of successful partner engagement. ### How It Works When you preview an opportunity before sharing it with a cloud partner (AWS, Azure, or GCP), Fours can automatically fill in missing fields like company addresses, contact names, and more. This happens seamlessly in the background - you'll see the enriched data right in your preview. **To enable auto enrichment:** 1. Go to **Co-Sell** → **Settings** → **Configs** (the **Cosell Configs** section) 2. Find your partner configuration (AWS, Azure, or GCP) 3. Enable the **Auto-Enrich Referrals** option Auto-Enrich Referrals option enabled in Cosell Configs Once enabled, the enrichment will happen automatically whenever you preview opportunities for that partner. Your existing data is always preserved - only empty fields are filled in. ### What Information Is Needed For the enrichment to work effectively, your CRM data needs to have some basic information about the company and contacts. **For company information**, the service needs at least: - Company name, or - Company website/domain **For contact information**, the service needs at least: - Contact email address, or - Contact first and last name (along with company information) If these basic fields are missing in your CRM data, the enrichment service won't be able to find additional information for that record. :::warning In some cases, our enrichment service may not be able to find information for certain companies. ::: ### What Fields Can Be Enriched The auto enrichment feature can fill in many commonly required fields for each cloud partner. Here's what can be automatically populated: #### AWS **Company Information:** - Company name and website - Full address (country, state, city, street address, postal code) - Industry classification **Contact Information:** - Email address - First and last name - Job title #### Azure **Company Information:** - Company name - Full address (country, state, city, street address, postal code) **Contact Information:** - Email address - First and last name - Job title #### GCP **Company Information:** - Organization name and domain - Full address (country, state/province, city, postal code, street address) - Industry classification - Company region - Employee count **Contact Information:** - Email address - First and last name (given name and family name) --- Source: https://doc.fours.com/cosell/cosell-inbound/ # Inbound Referral Manage inbound referrals shared by partners --- ## Fours Console - Co-sell Inbox In Fours Console, the Co-sell Inbox tab is the place to check all inbound referrals from cloud partners. Click on any item from the list to check the details: > Inbound referral detail view in the Co-sell Inbox You can accept the referral by clicking the `Accept` button on the top right: > Accept button on a referral detail page The pop-up will guide you through the process to: 1. Select an Account (company). If there is no existing account you would like to use, you can also create a new one right in the dialog. 2. Populate the opportunity detail. Most fields will be auto-populated if you have configured the field mappings & templates. 3. Click `Submit`. Fours will create the opportunity in your CRM, and notify the cloud partner that we would like to accept this referral, with the associated CRM record ID. **Microsoft referrals without an account ID** Some inbound Microsoft referrals arrive without an account ID. Accepting one of these is still allowed, but Fours asks you to confirm first rather than accepting silently — confirm to proceed, or cancel and set the account first. **Contact Information of AWS Referrals** - The contact information will be shared **10-30min** after you accepted it. - Upon receiving the contact info, we will automatically create the contact in your CRM - Before creation, we will check if a contact with the same last name and email address already exists for this Account/Company. If yes, then we will skip it. - After creation, we will also assign the Contact Role (Salesforce) or Association Type (HubSpot) as you configured in the field mappings. - To disable this behavior, set the SyncMode of contacts to `None` so we don't create/edit any contacts. ## Using Suger Connector in Salesforce All incoming referrals will be created as the "Referral (Suger)" records in your Salesforce, and you can check the list by going to the "Referrals (Suger)" tab. > Referrals (Suger) list tab in Salesforce To accept the referral, click on any of the pending acceptance ones, and click the `Accept` button on the top right. > Accept button on a Referral (Suger) record in Salesforce First, select or create an opportunity: > Select or create an opportunity dialog in Salesforce Then, click next and fill in the form to create the opportunity: > Opportunity creation form in Salesforce By default, the Account/Opportunity creation form only includes the fields that you have configured field mapping on Fours Console. To add more fields without field mapping, please ask your Salesforce Admin to configure the `Creation from Referral` Field Sets for Opportunity/Account. ## AWS Referral — Field Timing AWS populates fields on the `Suger__Referral__c` record in **two waves**: 1. **At invitation time** (before you accept) — a thin snapshot with customer company / industry / country / website, project title / problem / target date, and one expected-spend figure. Enough to triage and route the referral. 2. **After you accept** — AWS creates an Opportunity in your catalog, and Fours syncs the full record back. Lifecycle, team contacts, marketing attribution, software revenue, and insights arrive at this point. Customer contact details (name, email, phone) are shared by AWS **10–30 minutes after acceptance**, not immediately. The invitation and the opportunity it becomes share **one** `Suger__Referral__c` row. The AWS sender's covering note on the invitation is written to its own **Invitation Message** field rather than to Additional Comments, so accepting the referral does not overwrite it — the note stays readable on the record after acceptance. Alongside it, Fours backfills the partner acceptance status (`Pending` / `Accepted` / `Rejected`, plus the rejection reason when there is one), the engagement invitation ARN, and the **Accept By** expiration date. ### Declining an invitation When you decline an AWS engagement invitation, the reason you type is **sent to AWS** — it is no longer collapsed to "Other". AWS accepts free text here, but enforces a shape, so Fours validates it in the dialog rather than letting AWS reject it as an opaque partner-API failure: | Rule | Detail | | ---- | ------ | | **Length** | 1 to 80 characters. | | **Single line** | No line breaks. | | **Printable characters only** | No control characters and no emoji. | AWS's own documentation names five example reasons — *Customer problem unclear*, *Next steps unclear*, *Unable to support*, *Duplicate of partner referral*, *Other* — but these are guidance for AWS's usage tracking, **not a closed list**. A specific reason in your own words is legitimate and more useful to the AWS team reading it. The same validation applies wherever you decline: the lead detail page, and the reject action in the [Salesforce app](/salesforce-app/salesforce-app-cosell/). For the complete list of AWS fields on the Referral object — and which wave each field is populated in — see [Custom Objects → AWS Fields](/salesforce-app/salesforce-app-custom-objects/#aws-fields). ### If accepting or declining an AWS invitation fails When an accept or a decline fails, the invitation page shows the error in a message such as *Failed to accept invitation: …*. Nothing about the referral moves: it is not marked Active or Rejected, and its status stays what it was. The failure is recorded on the referral instead, so it stays visible after the message disappears. The status tag carries a red **!**, and hovering over it shows the reason (see [Failures that don't change the status](/cosell/cosell-status/#failures-that-dont-change-the-status)). The same happens when an invitation fails under [Auto-Accept](/cosell/cosell-configuration/#auto-accept-referrals). **What to do:** retry. **Accept** and **Decline** stay available for as long as the invitation is still pending, and a successful retry clears the red **!**. If the invitation is no longer pending (for example, it has already been accepted), Fours refuses the action and does not mark the referral. ## AWS Partner Central Leads AWS also sends **leads** — earlier-stage prospects, ahead of a full ACE opportunity. They arrive on their own inbound track and are worked from the **Lead** filter rather than the Co-sell Inbox. See [AWS Partner Central Leads](/cosell/cosell-leads/). --- Source: https://doc.fours.com/cosell/cosell-funding/ # AWS Funding Activate, submit, and track AWS funding requests directly in Fours. --- ## Overview Fours connects directly to the AWS Partner Central Funding Benefits API, so you can submit, track, and manage funding requests without leaving your workflow. Once funding is activated, you can create requests from either the Fours Console or your CRM, follow them as they move through AWS review, respond to rejections, file cash claims, and reconcile against your funding wallets. The **Funding** page in the Fours Console has two tabs: | Tab | What it holds | | --- | --- | | **Funding Request** | Every request you have created, with its status and stage. This is where you draft, submit, and work a request. | | **Wallet** | Your available budgets, remaining balances, and historical spend across AWS programs. | Before funding can be activated, two prerequisites must be in place. Once those are confirmed, a Fours admin enables funding on your ACE integration and (for Salesforce users) assigns the funding permission set. ## Prerequisites Make sure the following are in place before creating a funding request: ### 1. AWS ACE connected to Fours - Your AWS ACE integration must already be set up and active in the Fours Console (go to **Settings > Integrations** to verify). - This connects Fours to your AWS Partner Central account via the Partner Central API. - If you have not yet set up this integration, complete it first before proceeding. See [AWS Partner Network API Integration](/integrations/aws-partner-network-api/). ### 2. ACE portal migrated to Partner Central 3.0 (PC 3.0) - Your ACE portal must be fully migrated to Partner Central 3.0. - This migration is a mandatory AWS requirement before funding benefits can be enabled. - The Funding Benefits API is only available on the PC 3.0 platform. - Contact your AWS Partner Manager if you are unsure of your migration status. :::warning The Funding Benefits API only works with AWS Partner Central 3.0. If your account has not been migrated, funding requests will return errors. Enable **Enable Funding Application** only after your Partner Central 3.0 migration is confirmed. ::: ## Activate funding Before your team can submit requests, a Fours admin needs to enable the funding feature and (for Salesforce users) set up CRM permissions. ### Enable funding in the Fours Console Once both prerequisites are satisfied: 1. Log in to the [Fours Console](https://console.suger.io). 2. Go to **Settings** and click the **Integrations** tab. 3. Find your AWS ACE integration and click **Edit** to open the configuration panel for **AWS - ACE (Partner Central API)**. 4. Turn on the **Enable Funding Application** toggle (“Enable funding application for AWS”), then click **Save**. > Edit Integration modal for AWS ACE showing the Enable Funding Application toggle This step uses the Partner Central Funding Benefits API and only works after AWS has confirmed your Partner Central 3.0 migration. If migration is not complete, enabling funding will fail with an error. ### Set up Salesforce permissions (Salesforce users only) Without this permission set, team members will not be able to see the funding interface inside Salesforce. 1. Go to **User settings** in Salesforce. 2. Assign the **Suger Funding** permission set to each team member who will draft or submit funding requests. ## Choose a funding program Fours offers **seven** funding programs when you create a request: | Program | What it funds | | --- | --- | | **Market Development Funds** | Marketing activity that builds pipeline around your AWS solution. | | **Proof of Concept** | A customer proof of concept or pilot on AWS. | | **Migration Acceleration Program** | A customer migration to AWS, applied for per migration phase. | | **ISV Workload Migration** | Migrating an existing ISV workload onto AWS. | | **MPOPP Grow** | Marketplace Partner Opportunity Program (Grow) credits. | | **PIF: SCA GenAI Proof Of Concept Funding** | A generative-AI proof of concept under the Strategic Collaboration Agreement. | | **PIF: SCA GenAI Marketing Development Funds** | Generative-AI marketing activity under the Strategic Collaboration Agreement. | ![The Create Fund Request menu — the funding programs you can start from the console](images/51-funding-programs-menu.png) :::note The two **SCA GenAI** programs were withdrawn for a period and have since been restored. They are available again in the **Create Fund Request** menu, the opportunity actions menu in the [Salesforce app](/salesforce-app/salesforce-app-cosell/), the Suger card on a HubSpot deal, and the program dropdown on the funding field-mapping configuration page. Both support **Cash** and **Credit**. ::: ## Submit a funding request Once funding is activated, you can create a request from either the Fours Console or your CRM. :::info Before creating your request, make sure you know which fields AWS requires for your chosen program. Incomplete submissions will be rejected and require correction before resubmission. ::: 1. Open the **Funding Request** tab in the Fours Console, or go to the relevant opportunity in Salesforce and open the Fours component. 2. Click **Create Fund Request** and select one of the seven funding programs above. 3. Fill in all required project details. Use the built-in validation tool to check for missing or incorrect fields before submitting. This catches errors before they reach AWS, which helps avoid delays. - If your POC request is over $10,000, AWS requires an AWS Pricing Calculator link plus a project plan. The MRR you enter in ACE must exactly match the calculator's output — even a small mismatch gets the request rejected. Double-check this before submitting; it's the single most common reason POC requests get sent back. 4. Click **Submit**. Fours sends the request directly to the AWS Partner Central API. ### Migration Acceleration Program requests The Migration Acceleration Program (MAP) has its own requirements on top of the standard project details: | Requirement | What to supply | | --- | --- | | **Migration phase** | Choose **Assess** or **Mobilize**. | | **ARR** | The annual recurring revenue for the migration, which must be at least **100,000**. | | **VMware attestation** | Required on **Mobilize** only. It is not asked for on an Assess request. | | **AWS opportunity** | A MAP request associates an **AWS opportunity** — it is not drawn against a wallet. | #### The MAP request form in Salesforce Salesforce users raise a MAP request from the Fours funding table on the opportunity: open the **New Funding Request** menu and choose **New Migration Acceleration Program Request**. That opens a dedicated MAP form rather than the generic funding form. **MAP is cash-only.** There is no cash-or-credit choice to make — every MAP request is submitted as a cash request, which is why the form always includes a Cash Request Detail section. The form is organized into five sections: | Section | What it collects | | --- | --- | | **Migration Details** | The **Migration Phase** (Assess or Mobilize), **Annual Recurring Revenue (ARR)** — which must be at least 100,000 — and, on Mobilize only, the attestation that over 75% of the servers being migrated are VMware-hosted VMs. | | **Opportunity Information** | The **AWS Opportunity** the request is associated with. Just the one field. | | **Project Information** | The requester's first name, last name, email address and job title; project name, business description, AWS Account ID, **Project Start Date (UTC)**, **Project End Date (UTC)**, the country and states the activity is executed in, and an optional AWS Pricing Calculator link. | | **Cash Request Detail** | Currency, total cost of the project, total amount requested from AWS, and the **Payee Central Account Profile ID**. | | **Supporting Documents** | Any documents you need to attach to the request, each with its type — see [Attach supporting documents](#attach-supporting-documents). | Two date rules shape the request, and they are worth planning around: - **Project Start Date** — the form will not accept a date less than **14 days** from today. AWS's own guidance, shown on the field, is that work must start at least **14 business days** after you submit, which is the longer of the two — so leave more room than the picker strictly demands. - **Project End Date** — cash claims are due **30 days** after this date. The form does not enforce that deadline; it only requires the end date to fall on or after the start date. :::warning **Payee Central Account Profile ID is required.** It must be **10 to 13 alphanumeric characters** and comes from your Payee Central profile. The form rejects anything outside that pattern, and because MAP is a cash program the request cannot be submitted without it. ::: ### Fields you may be looking for A few fields have changed, and knowing which are gone saves time hunting for them: | Field | Status | | --- | --- | | Invoice fields | **Removed.** Invoicing is handled in Payee Central, not in the request. | | **Payee Central account profile ID** | **Required for cash programs.** A 10–13 character identifier from your Payee Central profile. | | Public Sector Agreement checkbox | **Removed.** | | WWPS consent | Still present — continue to answer it on public-sector requests. | | **Customer Also Considering** | **Required on MPOPP Grow requests in the Fours Console.** MPOPP Grow is the only console program form that asks for it: choose the alternative the customer is also weighing, such as **Microsoft Azure**, **On-Premise**, or **No Competition**. It is a funding field-mapping target on MPOPP Grow configs only. | ### Attach supporting documents Each program's request form has a **Supporting Documents** section. In the Fours Console, click **Add Attachment** once per file, pick the file's type, and upload it. The type is the business use case AWS files the document under; the console labels the picker **Attachment Type** on Market Development Funds, PIF: SCA GenAI Marketing Development Funds, and ISV Workload Migration requests, and **Business Use Case** on the other programs. Every program except ISV Workload Migration offers the same 19 types: Project Plan/Checklist, Innovation Plan, Marketing Plan, Proof of Cost, Assess Analysis Report, Well Architected Review Report, Success Criteria Report, Customer Sign Off Template, Partner Sign Off Template, Customer Satisfaction Survey (CSAT), Migration Capability Review, Migration Completion report, AWS Pricing Calculator, Migration Assessment Scope Checklist, Statement of Work, Migration Assessment Report, Managed Services Agreement, Partner Scope Checklist, and Other. ISV Workload Migration offers seven of them: Project Plan/Checklist, Migration Assessment Report, AWS Pricing Calculator, Statement of Work, Customer Sign Off Template, Partner Sign Off Template, and Other. The lists are the same in the Fours Console, the Salesforce app, and on a HubSpot deal. :::note **Business Case** and **Quote** are not attachment types AWS accepts. Market Development Funds requests used to offer them, and a request that still carries an attachment typed either way is rejected when it is submitted to AWS. Change that attachment's type — to **Marketing Plan** or **Other**, for example — and submit again. ::: ### Create AWS funding from a HubSpot deal You do not have to start in the Console or in Salesforce. HubSpot users can raise a request straight from the deal they are working. 1. Open the deal in HubSpot and find the Suger card on the deal record. 2. Click **New Funding**. 3. Complete and submit the request as usual. :::note The HubSpot deal card offers all seven programs, with the same funding types as the console. See [Create Funding](/hubspot-app/hubspot-app-funding/) in the HubSpot app docs for the card itself. ::: To control how HubSpot deal fields populate a funding request, open the funding mapping configuration page in the Fours Console and set the **CRM Source** dropdown to **HubSpot** (the other option is **Salesforce**). Each CRM source keeps its own mapping, so configuring HubSpot does not disturb an existing Salesforce mapping. ![The funding field-mapping page for MDF / CASH — the CRM Source dropdown open at the top showing Salesforce (selected) and HubSpot, above the per-field mapping rows with their AWS field name, the CRM field they draw from, and the transform controls on each row](images/60-funding-crm-source.png) Funding mappings live on the **Funding** page's **Settings** tab, which sellers and resellers see ([open it](https://console.suger.io/funding?tab=settings)); it moved there from the console's main **Settings** page, and an old `settings?tab=funding` link still lands on it. Under **Funding Configs**, each saved mapping is its own card, named for its CRM, program, and funding type — for example, `AWS - HubSpot / Market Development Funds / CASH`. A Salesforce mapping and a HubSpot mapping for the same program sit side by side as two cards. **New Config** asks for the **CRM Partner** (Salesforce or HubSpot), **Program Type**, and **Funding Type** before it opens the mapping page, and deleting a card removes only that card's mapping. ### Test a funding field mapping Before your team relies on a mapping, check what it produces for a real record. On the funding field-mapping page, click **Test** to open the **Test Funding Field Mapping** dialog: 1. Pick the source record. For **Salesforce**, select or search for an opportunity; the test runs as soon as you pick one. For **HubSpot**, enter the deal ID and click **Run**. 2. Read the **Result JSON**. `preview` holds the funding request the mapping built from that record, and `validate` lists the fields that would fail validation. The same mapping pre-fills a new funding request started from a CRM record, so the test shows what your team will see when they start one. How mapped values are read: - **List fields get a list.** AWS fields that take several values, such as the states where the activity is executed, receive a list even when the mapping yields a single value: `CA` becomes `["CA"]`, and semicolon-separated multi-select picklist values are split into separate items. - **Blank stays blank.** An empty CRM field adds nothing to an expression's output, so an expression that reads only that field produces an empty value. - **Salesforce: fields on related records resolve.** A mapping can read beyond the opportunity itself, for example `Account.BillingState`, in direct mappings, expressions, and AI prompts. - **Salesforce: a field that can't be queried doesn't stop the preview.** The preview continues from the base record only (the opportunity and its account) and adds a warning on `_source` that starts with `failed to query configured source fields, using base record only:`, followed by the query error. ## Track the funding lifecycle After submission, Fours keeps your request synchronized with AWS. To stay on top of where a request stands, track two separate data points: - **Status** — where the request stands: the status AWS reports (for example, `PENDING_SUBMISSION`, `IN_REVIEW`, `APPROVED`, or `REJECTED`) and the request's status in Fours. See [Read the status](#read-the-status). - **Stage** — how far the request has moved through AWS's fund request process, from creation through the approvals to completion. See [Read the stage](#read-the-stage). :::info **Stage is driven by AWS and is read-only.** Fours renders it as a stepper showing where the request has reached in the AWS review — it is not a list you configure, and there is nothing to add, rename, or reorder. The stage advances when AWS advances it. ::: Funding data is refreshed on a schedule, roughly **every three hours** — not in real time. A status or stage change made on the AWS side appears in Fours on the next sync rather than the moment it happens. To filter and prioritize your requests, use the **Advanced Filters** in the Fours Console or your CRM. You can filter by program type, fulfillment type (Credits or Cash), or stage. ### Read the status The **Funding Request** tab has two status columns. **Partner Status** is the status AWS reports for the request — **Pending Submission**, **In Review**, **Action Required**, **Approved**, **Rejected**, or **Canceled** — and **Status** is the request's status in Fours. **Pending Submission** means the application exists on AWS but has not been submitted for review: AWS gives a new application that status when it is created and returns a recalled one to it ([Working with benefit applications](https://docs.aws.amazon.com/partner-central/latest/developer-guide/working-with-benefit-applications.html)). Fours records a request in that state as **Create Failed**, but the **Funding Request** tab displays it as **Created**, not as a red failure. Only the label in the tab changes: on the request's own page, **Active Status** still reads **Create Failed** next to a **Partner Status** of **Pending Submission**. To send the request for review, open it and choose **More actions** > **Re-submit**. ### Read the stage The stepper at the top of a request's page in the Fours Console has six steps — the same six AWS Partner Central shows for a fund request's progress. Every step up to and including the request's current one is checked, and the current step's name is highlighted. ```d2 direction: right creation: "Application\ncreation" business: "Business\napproval" finance: "Finance\napproval" pre: "Pre-approval" claim: "Cash claim" complete: "Application\ncompletion" creation -> business -> finance -> pre -> claim -> complete ``` AWS reports the stage in its own terms, and Fours places the request on the matching step: | Step | Stage AWS reports | | --- | --- | | **Application creation** | No stage yet — for example, a request that has not been submitted — or a value Fours does not recognise | | **Business approval** | `BUSINESS_APPROVAL` | | **Finance approval** | `FINANCE_APPROVAL` | | **Pre-approval** | `PRE_APPROVAL` | | **Cash claim** | `Invoice` or `Disbursement` — the claim's two steps | | **Application completion** | `FULFILLMENT` | The Salesforce app's funding page shows the same stepper once AWS has reported a stage. Where the stage appears as a label instead — the **Stage** column of the **Funding Request** tab, the Salesforce app's funding table and opportunity card, and the funding details on a HubSpot deal — it uses the same names, and a value Fours does not recognise is shown exactly as AWS sent it. Until AWS reports a stage, the console's **Stage** column is empty, the Salesforce app shows a dash, and the HubSpot deal card leaves the field out. The stage filter — **Stage** in the console, **Fund Request Stage** in the Salesforce app — offers **Business approval**, **Finance approval**, **Pre-approval**, **Cash claim (invoice)**, **Cash claim (disbursement)**, and **Application completion**. A request with no stage yet matches none of them. ## Respond to action required and rejections If a request is paused or rejected, Fours gives you what you need to fix and resubmit without starting over. ### If a request is flagged as `ACTION_REQUIRED` 1. Open the request and check the **Status Reason Codes**. These indicate exactly what is missing, such as a project plan or design win document. 2. Update the request in Fours based on the reason codes. 3. Resubmit to restart the review process. ### If a request is rejected 1. Review the rejection reason. You can find it in the automatic rejection email, in the **Approval History** in the action bar, or under the **Actuals** section of the request. 2. Select **Resume fund request** from the action bar to reopen and update the request. 3. Submit once your changes are complete. ## Submit and track cash claims Once a project is complete and your request has been approved, you can file a claim to receive your reimbursement. :::note **There is no separate "MAP Cash Claim" program.** The cash claim was a legacy benefit of MAP, and it has been replaced by the [**Migration Acceleration Program**](#migration-acceleration-program-requests) entry in the program list. Apply for MAP as a program in its own right — choosing a Migration phase, supplying ARR, and associating an AWS opportunity — rather than looking for a cash-claim program to apply to. ::: **A cash claim is not a second row in the Funding Request tab.** Allocations fulfilled by a disbursement are filtered out of that tab, so its counts and its list hold funding *requests* only. Track the claim from the request it belongs to, not by looking for a separate entry. Cash claims themselves still work the same way on any approved cash-based request: 1. Navigate to the **Cash claim** stage for the approved request. 2. Submit your actual project expenses (actuals). 3. The status updates to **Awaiting Approval** while AWS reviews your submission. 4. Once AWS approves, Fours provides a direct link to Payee Central where you can submit your invoice. 5. Track the claim until the invoice is approved and the reimbursement is finalized. :::info For credit-based requests, the request stays in the **Pre-approval** stage until all credit codes are disbursed. For cash-based requests, Pre-approval is the final waiting period before you can file a claim. ::: ## Monitor wallets and purchase orders Open the **Wallet** tab on the Fours **Funding** page to see your available budgets, remaining balances, and historical spend across all AWS programs. Not every program draws on a wallet — a **Migration Acceleration Program** request is associated with an AWS opportunity instead, so it does not appear as wallet spend. To support internal reconciliation, open the funding details for any request to find the PO numbers associated with your approvals. In the Salesforce app, the Funding Detail page's **Cash Request Information** section shows the **PO Number** and the **Payee Central Account Profile ID** for MDF and POC cash requests, and both sync to the Salesforce Funding record — see [How Funding records open](/salesforce-app/salesforce-app-settings/#how-funding-records-open). ## Frequently asked questions **Can I edit a request after submitting it?** Once submitted, a request's status becomes `IN_REVIEW`, and it can no longer be edited through standard means. For minor corrections requested by AWS reviewers, use the **Amend fund request** option in the action bar. **Can I update a draft before submitting?** Yes. You can edit a draft at any time while it is in `PENDING_SUBMISSION` status. **Can I link a request to a specific opportunity?** Yes. Before submitting, you can associate the request with a related customer opportunity or an existing benefit allocation from within the request builder. **What happens if my request fails validation on submission?** Fours will show you the specific fields that need to be corrected. Update those fields and resubmit. **Why doesn't my ACE opportunity show up when I submit an MPOPP (Marketplace Partner Opportunity Program) request?** This is a known AWS Partner Central 3.0 bug tied to CPPO-to-ACE association. Before resubmitting, confirm the Marketplace Offer ID is linked to the opportunity — this is the root cause in most cases. **Why have my funding requests stopped updating?** If AWS reports that your AWS account is no longer an active AWS partner, Fours pauses the scheduled funding sync for your organization, because retrying cannot succeed until that changes. Once your partnership is restored, contact [support@suger.io](mailto:support@suger.io) to have the sync resumed. --- For assistance with any step in this guide, contact your Fours Customer Success Manager. --- Source: https://doc.fours.com/cosell/co-sell-insights/ # Co-Sell Insights Fours Insights powered by AWS Co-Sell Agents. --- ## Overview The Fours Widget **Insights Tab** uses pre-defined triggers to evaluate your opportunity data. It then surfaces actionable cards powered by AWS Co-Sell AI Agents to provide proactive guidance on deal progression, funding eligibility, and risk mitigation. ## Prerequisites To use these AI-powered features, the following must be in place: - **AWS PC 3.0 Migration**: Your ACE account must be migrated to AWS Partner Central 3.0. - **Co-sell AI enabled by Fours**: The Cosell-AI feature is switched on by Fours, not by your team. Contact [support@suger.io](mailto:support@suger.io) to have it enabled for your organization. > Cosell-AI toggle under AI Feature settings ## How it Works The Insights Tab is organized around three distinct card types, following a strict visual hierarchy: ### 1. Warning Cards (Fours-Computed) These are deterministic alerts rendered immediately at the absolute top of the AI Tab. - **Visibility**: Always visible when a trigger condition is met (e.g., an opportunity hasn't been updated in 30+ days). - **Interaction**: These often include inline CTAs like "Update Close Date". You can dismiss them for the current session, but they will reappear on your next visit if the condition persists. > Warning card alert in the Insights tab ### 2. Main Insight Cards (AWS MCP Powered) These cards are fetched from AWS MCP when the AI Tab loads and are cached for approximately 10 days. - **Opportunity Insights**: Provides a summary of general opportunity health, engagement scores, and quick wins. - **Funding Insights**: Surfaces eligibility for programs like POC funding or MDF (available for approved/accepted opportunities). ### 3. AI Trigger Cards (Recommended Actions) These cards map to specific conditions in the AWS ACE opportunity lifecycle and appear grouped beneath their parent Insight Card. - **Interaction**: Click a card (e.g., "Help me progress this opportunity") to expand it. - **Examples**: "Why was this rejected?", "Request POC funding", or "Get pricing and business case support". > AI trigger cards grouped under an Insight Card ## AWS Opportunity Quality Score Before you submit an opportunity to ACE, Fours predicts how AWS is likely to rate its quality — so you can improve it while editing rather than after a rejection. :::info The quality score is **AWS-only**. There is no Azure or GCP equivalent, and the banner does not appear on referrals to those partners. ::: ### Where you see it The score appears as a **Predicted AWS quality score** banner in the ACE submission dialog. After you change the fields the score depends on, click **Re-analyze** to score the opportunity again with your edits. ![The ACE submission dialog with the Predicted AWS quality score banner at the top — the score out of 100 beside its band badge and a Re-analyze button, a one-line verdict, the per-dimension breakdown as earned/weight pills, and the ranked list of fixes with the points each would add](images/62-ace-quality-score.png) When AWS has scored the opportunity in ACE, its own score appears on the referral too. On an AWS referral's detail page, the **AWS Opportunity Quality** panel at the top of the right sidebar shows AWS's **Quality Score**, with the **Quality Trend**, the **Co-Sell Motion**, and the **AWS Recommendation**. The info icon beside the score reads *AWS's quality score for this opportunity in ACE, as reported by AWS.* That score is AWS's, not Fours' prediction. The panel is hidden until AWS has returned at least one of these. ### How the score is read The score runs from **0 to 100** and falls into one of five bands: | Band | Score | | --- | --- | | **Lowest** | 0–10 | | **Low** | 11–25 | | **Medium** | 26–39 | | **High** | 40–49 | | **Highest** | 50 and above | The number comes from a rubric of **8 weighted dimensions** evaluated across the opportunity — no single field decides it, so improving one weak area moves the score rather than transforming it. ### The business-problem gate One check overrides everything else. If the **Customer Business Problem** is a placeholder, too short, or reads as a pitch for your product rather than a description of the customer's problem, the score is forced to **0** regardless of how strong the rest of the opportunity is. That gate is deliberate: AWS partner managers read the business problem first, and a weak one sinks an otherwise good opportunity. If your score is 0, rewrite the business problem before looking at anything else. ## Generate the Customer Business Problem with AI Because the business problem carries so much weight, Fours can draft it for you. Use **Generate with AI** on the **Customer Business Problem** field. **Generate with AI** is part of the ACE submission dialog for the [AWS Partner Central API integration](/integrations/aws-partner-network-api/). It is not available on the deprecated [legacy S3 integration](/integrations/aws-partner-network-s3/). What you get back: - **2–4 sentences**, written **from the customer's perspective** — the problem they have, not the product you sell. - Length inside AWS's expectations. The existing rule still applies: Fours instructs the AI to produce **500–1,800 characters** and truncates anything over 1,800. If your organization has defined its own prompt for this field in the co-sell field mapping configuration, that prompt is used instead of Fours' default — so you can steer tone and emphasis for your whole team in one place. See [Field Mapping](/cosell/cosell-configuration/) for where the prompt lives. ## Engagement Score The engagement score estimates how engaged a customer already is with a cloud partner. It is reported as one of three values: **`High`** · **`Medium`** · **`Low`** Fours resolves it from the best source available, in order: 1. **Partner** — the score the cloud partner itself reports for the customer. 2. **Marketplace** — derived from the customer's activity on that partner's marketplace, used when the partner reports no score. 3. **AI** — an AI-derived estimate, used as the fallback when neither of the above is available. The score is refreshed every **6 hours**, so a newly created customer record may take a cycle before a score appears. ### Two different scores, named apart A cloud partner may score a specific opportunity itself. Where it has not, Fours predicts one instead. These are different things, so they carry different names rather than being tagged: | What you see | What it is | | --- | --- | | **Fours Predicted Engagement Score** | Fours' own prediction, from the customer's marketplace listings and purchases and from AI analysis of third-party signals. | | A score on the referral, under **Engagement Score** | The cloud partner's own score for that opportunity. | | **Not provided by AWS** | AWS has not scored this opportunity. Only AWS referrals show this, because Azure and GCP never supply a score of their own. | **Azure and GCP never supply an engagement score of their own**, so a score shown for either is always Fours' prediction. Fours' prediction appears in the Fours widget on the Account and Opportunity pages, under its own heading. It is deliberately not shown on an AWS referral: the referral's score is AWS's own, and mixing the two there is what used to make a prediction look like a number AWS had supplied. Azure and GCP referral cards in the Salesforce app have no partner score to confuse it with, so they show a row labelled **Suger Predicted Engagement Score** instead (N/A when Fours has no prediction). In HubSpot, the prediction appears on the deal's **Insights** tab and on the **Co-sell Insights** company card. See [Engagement score on the Insights tab](/hubspot-app/hubspot-app-cosell/#engagement-score-on-the-insights-tab). ### Only a partner score reaches your reports This is the part worth knowing before you build a report. In Salesforce, only the partner's own score for that opportunity is written to the referral record's **AWS Marketplace Engagement Score** field (`Suger__AWS_EngagementScore__c`). The **Suger Predicted Engagement Score** is calculated for display and stored against the customer's domain in Fours, not on the referral — so it appears in the Fours widget and is blank in any report, list view, formula field or automation built on that field. A blank column in a report therefore means one thing: **AWS has not scored that opportunity yet.** It does not mean the score was lost. The same note appears on the field itself, in the help text beside **AWS Marketplace Engagement Score** on the referral record. --- Source: https://doc.fours.com/cosell/cosell-referral-api/ # 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](/cosell/cosell-outbound/) UI walkthrough. It documents the request payload for one endpoint: ``` POST /org/{orgId}/cosell/referral ``` - **Auth:** API key (`Authorization` header). See [Authentication](/get-started/). - **Query param:** `forceCreate` (boolean, optional). When `true`, the referral is saved in Fours even if it fails validation or the partner rejects it, so you can fix and resubmit later. Default `false`. - **Response:** `200` with an `OperationExecutionDetails` object (contains the `workflowID` of the submission). On validation failure you get `400` with an `info` array of per-field errors (see [Validate first](#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](#response--next-steps)). :::note If your org has the **referral approval process** enabled and the referral is not yet approved, a brand-new referral is saved as `DRAFT` and the workflow does **not** fire until it is approved in the Fours Console. ::: ## The envelope Every request body has the same outer shape, regardless of cloud: ```jsonc { "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 */ } } ``` :::note[Linking to Salesforce] `salesforceOpportunityId` and `salesforceAccountId` are optional — set them to associate the referral with a CRM record so it shows up linked in the Fours Console and stays in sync. If you provide `salesforceOpportunityId` but leave `salesforceAccountId` blank, Fours automatically derives the account from that opportunity. Set `salesforceAccountId` explicitly only when you want to control or override which account is linked. This applies to all three clouds. ::: 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 | :::note[Azure: what you send vs. what you get back] On **create** you send `info.createMicrosoftReferralRequest`. Fours converts it internally and persists it as `info.microsoftReferralSet`, so `GET` responses return the referral under `microsoftReferralSet` — not `createMicrosoftReferralRequest`. Always build the create payload with `createMicrosoftReferralRequest`. ::: ### Two tiers of "required" Throughout this page, required fields fall into two groups: - **Required by Fours** — missing/invalid values return a `400` *before* 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. Nothing is created or sent: ``` POST /org/{orgId}/cosell/referral/validate ``` The body names the partner and carries the partner-specific opportunity — the object you would put in the envelope's `info` slot, not the whole envelope: ```jsonc { "partner": "AWS", // "AWS" | "GCP" | "AZURE" — a Fours partner (SUGER) referral can't be validated "opportunity": { /* what you'd send under info.aceOpportunityV2, info.gcpOpportunityV2, or info.createMicrosoftReferralRequest */ }, "referralId": "..." // optional: only when validating a change to an existing referral } ``` Pass `referralId` when you validate a change to a referral that already exists, so it is not reported as a duplicate of itself. The answer is a `200` whether or not the opportunity passes, so you can correct the payload without creating a `CREATE_FAILED` record: ```jsonc { "valid": false, "errors": [ { "field": "customer.account.industry", "message": "'Industry vertical' is required" }, { "field": "relatedEntityIdentifiers.solutions", "message": "'Solutions' is required" } ], "duplicateOpenReferrals": [ // advisory; omitted when there are none { "referralId": "...", "title": "Acme Corp — Migration", "partner": "AWS", "status": "IN_REVIEW", "externalId": "O1234567" } ], "normalizedOpportunity": { /* the opportunity as the partner would receive it */ } } ``` - **`valid` and `errors`** are the verdict. A `400` from this endpoint means the request itself is malformed — no `partner`, an unsupported partner, or an opportunity that can't be read. - **`duplicateOpenReferrals`** lists still-open referrals for the same partner with the same title. It never changes `valid` and never blocks a create. - **`normalizedOpportunity`** is the opportunity after the partner's validator has normalized it — what the partner would actually receive. Validators silently blank, shorten, or drop values they can't accept — on AWS, for example, an invalid AWS account ID is blanked, `AdditionalComments` is cut to 255 characters, and `SoftwareRevenue` is dropped for an ineligible partner type — so compare it with what you sent. For Azure, `valid` and `errors` come from strict validation, while `normalizedOpportunity` shows the payload after Fours' automatic corrections, which is what a create would submit. If you create a referral without validating it first, the same problems come back on the create call as a `400` with an `info` array of per-field errors: ```jsonc { "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](#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](#where-solution-ids-come-from) | | `LifeCycle.TargetCloseDate` | `YYYY-MM-DD`, subject to the [close-date policy](#the-targetclosedate-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](https://docs.aws.amazon.com/partner-central/latest/APIReference/API_CreateOpportunity.html). ### 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 }`; `id` is what goes in `Solutions` - `info.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 (`AWS` or `Sandbox`). Don't send it. - `Project.ExpectedCustomerSpend[0]` — the first entry's `Frequency`→`Monthly`, `CurrencyCode`→`USD`, `TargetCompany`→`AWS` are always overwritten (AWS only accepts these for this object). You supply `Amount`. - `Marketing.Source` defaults to `"None"`; `Project.SalesActivities` defaults to `["Initialized discussions with customer"]` when empty or when every value is invalid. - `NationalSecurity` defaults to `"Yes"` when `Industry` is `"Government"` **and** you left it blank or sent something other than `"Yes"`/`"No"`. An explicit `"No"` is preserved. - `LifeCycle.Stage` is cleared if it isn't a valid stage. `Project.CompetitorName`, `Customer.Account.Duns` (9 digits) and `Customer.Account.AwsAccountId` (12 digits) are cleared if invalid. - `Project.AdditionalComments` and `LifeCycle.NextSteps` are truncated to 255 characters. - `OpportunityTeam` members with no usable email are **dropped**. Customer `Contacts` are not dropped — an unusable email or phone is just blanked. - `OpportunityTeam[0]` defaults to `BusinessTitle: "PartnerAccountManager"` and `OpportunityTeam[1]` to `"OpportunityOwner"`. The `PartnerAccountManager` also gets a default phone number if theirs is missing or unusable. - `SoftwareRevenue` — AWS accepts its five fields only when your AWS ACE integration's partner type is `ISV Accelerator Program Partner` or `SaaS Revenue Recognition Program`. For any other partner type, or none, Fours drops the whole block on create, and an update doesn't apply it. For an eligible partner type, Fours keeps what you send and fills in anything missing or invalid: | Field | When missing or invalid | | --- | --- | | `SoftwareRevenue.Value.Amount` | `Project.ExpectedCustomerSpend[0].Amount` when that is a positive number, otherwise `"0"`. An amount you send must be a positive number; it is rounded to two decimal places. | | `SoftwareRevenue.Value.CurrencyCode` | `USD`. A code outside AWS's currency list is dropped first. | | `SoftwareRevenue.DeliveryModel` | `Contract`. A value outside AWS's list is dropped first. | | `SoftwareRevenue.EffectiveDate` | `LifeCycle.TargetCloseDate`. Dates are sent as `YYYY-MM-DD`, and one that can't be read is dropped. | | `SoftwareRevenue.ExpirationDate` | `LifeCycle.TargetCloseDate` plus one year. An end date that isn't after the start date is replaced the same way — or set to a year after the start, when that default still wouldn't follow it. | ### 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](https://docs.aws.amazon.com/partner-central/latest/APIReference/API_CreateOpportunity.html). ### 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](https://docs.aws.amazon.com/partner-central/latest/APIReference/API_CreateOpportunity.html) as the source of truth for what AWS will accept. ```jsonc { "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": "dana.cruz@acmerobotics.com", "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": "sam.patel@yourcompany.com", "Phone": "+14155550100", "BusinessTitle": "PartnerAccountManager" }, { "FirstName": "Jordan", "LastName": "Lee", "Email": "jordan.lee@yourcompany.com", "Phone": "+14155550101", "BusinessTitle": "OpportunityOwner" } ], "Marketing": { "Source": "None" } // Suger fills "None"; if set to a real source, also provide CampaignName / Channels / UseCases / AwsFundingUsed } } } ``` > `Catalog` and `SoftwareRevenue` are intentionally omitted — Fours sets `Catalog` from your AWS integration, and AWS accepts `SoftwareRevenue` only from `ISV Accelerator Program Partner` and `SaaS Revenue Recognition Program` partners (see [Auto-filled / normalized by Fours](#auto-filled--normalized-by-fours) for how Fours fills it in). `PartnerOpportunityIdentifier` is 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](#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 employee`
`Agentify your business processes`
`AI in the flow of human ambition` | | `Cloud and AI Platforms` | `Modernize with confidence`
`Build a unified governed data and AI estate`
`Amplify your intelligence`
`Ubiquitous Innovation` | | `Microsoft Services` | `Accelerate AI Transformation with Microsoft Services` | | `Security` | `AI-ready productivity and security for every employee`
`Establish a trusted and secure platform for AI` | | `Windows and Devices` | `AI Transformation with Surface and Copilot` | :::note **`SolutionPlay` was renamed to `Conversation`.** Send `Conversation` on new referrals. `SolutionPlay` is still accepted — on create Fours rewrites it to `Conversation`, and on update it keeps whichever name you sent — but it is the retired name. Values from earlier Microsoft fiscal years are mapped forward automatically on create. See [Co-Sell Fields in Microsoft](/cosell/cosell-microsoft-fields/) for the fiscal-year rules and how legacy values are displayed. ::: #### `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](https://learn.microsoft.com/en-us/partner-center/developer/create-a-referral). ### 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. ```jsonc { "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": "sam.patel@yourcompany.com", "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`, and `dealType` for 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): ```jsonc "invitations": [ { "organizationId": "msft", "organizationName": "Microsoft", "assistanceRequestCode": "ProofOfConceptOrDemo" } ], "customerProfile": { "address": { "country": "US" }, "team": [ // required for co-sell: >= 1 customer contact { "firstName": "Dana", "lastName": "Cruz", "email": "dana.cruz@acmerobotics.com", "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** — `opportunityType` is `REGULAR` (or omitted / `TWO_TIER`). A standard resell/services opportunity. - **ISV Solution Connect** — `opportunityType` is `ISV_SOLUTION_CONNECT`. An ISV solution deal, with its own `isvSolutionConnectInfo` block. 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](https://docs.cloud.google.com/channel/docs/reference/rest/v1alpha1/opportunities). ### Example payload (GCP — Regular) ```jsonc { "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": "john.doe@acme.com", // 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) ```jsonc { "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": "jane.smith@techcorp.io", // 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_CREATE` while the submission workflow runs, then moves to the partner's accepted state — or `CREATE_FAILED` if the partner API rejects it. To resubmit, `GET` the referral, correct it, and `POST` it back to `.../cosell/referral` with the same `id` — Fours resubmits that referral in place. A body without the `id` creates 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. Two cases send nothing; see [Updating a referral](#updating-a-referral). ## 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. Two kinds of update are saved but not sent to the partner: - **The referral approval process is on.** For AWS, Azure, or GCP, an update to a referral that is not yet approved or submitted is saved as `DRAFT`, and nothing is sent until it is approved in the Fours Console. - **An AWS referral at `Launched` or `Closed Lost`.** A content update is accepted and saved in Fours, but the outbound sync skips a closed AWS opportunity, so the change never reaches AWS. - **Query param:** `isLinkageUpdate` (boolean, optional, default `false`). When `true`, 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_FAILED` can't be edited here.** AWS never accepted it, so there is nothing to update: resubmit it instead, by sending it back to `POST .../cosell/referral` with the same `id` (see [Response & next steps](#response--next-steps)). The `PATCH` is refused with `400`, and the referral is left unchanged: ```jsonc // excerpt of the 400 response "info": [ { "field": "status", "message": "referral 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 `null` clears it. The exceptions are `info.aceOpportunityV2.lifeCycle.reviewStatus` and `lifeCycle.stage`: they cannot be cleared, so sending either as `null` keeps 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`. Other `info` sub-documents — for example `aceEngagementInvitation` — are not preserved by an update. - **When it is rejected with `400`.** For a non-AWS partner, when combined with `isLinkageUpdate=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. :::tip AI agents and MCP clients should always send `merge=true`, so an omitted field is never mistaken for one you meant to clear. ::: ## 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): ```java Map referral = new Map{ '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{ 'aceOpportunityV2' => new Map{ 'Origin' => 'Partner Referral', // required 'OpportunityType' => 'Net New Business', // required 'NationalSecurity' => 'No', // optional 'Customer' => new Map{ 'Account' => new Map{ '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{ 'CountryCode' => 'US', // required 'StateOrRegion' => 'California', // required for US 'City' => 'San Francisco', 'PostalCode' => '94105', // required 'StreetAddress' => '123 Market St' } }, 'Contacts' => new List{ new Map{ 'FirstName' => 'Dana', 'LastName' => 'Cruz', 'Email' => 'dana.cruz@acmerobotics.com', 'Phone' => '+14155550123', 'BusinessTitle' => 'VP Engineering' } } }, 'PrimaryNeedsFromAws' => new List{ 'Co-Sell - Deal Support' }, // required 'Project' => new Map{ '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{ 'SaaS or PaaS' },// required 'ExpectedCustomerSpend' => new List{ new Map{ 'Amount' => '5000' } }, // required (Amount) 'SalesActivities' => new List{ 'Initialized discussions with customer' }, // Suger defaults if omitted 'AdditionalComments' => 'Joint GTM with the AWS account team.' // optional }, 'LifeCycle' => new Map{ 'TargetCloseDate' => '2027-06-30', // required (future, YYYY-MM-DD) 'NextSteps' => 'Schedule joint architecture review'// optional }, 'RelatedEntityIdentifiers' => new Map{ 'Solutions' => new List{ 'S-0123456' }, // required, >= 1 'AwsProducts' => new List{ 'AmazonBedrock' }// optional }, 'OpportunityTeam' => new List{ // your team (partner side) new Map{ 'FirstName' => 'Sam', 'LastName' => 'Patel', 'Email' => 'sam.patel@yourcompany.com', 'Phone' => '+14155550100', 'BusinessTitle' => 'PartnerAccountManager' }, new Map{ 'FirstName' => 'Jordan', 'LastName' => 'Lee', 'Email' => 'jordan.lee@yourcompany.com', 'Phone' => '+14155550101', 'BusinessTitle' => 'OpportunityOwner' } }, 'Marketing' => new Map{ '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 operation = (Map) result; String workflowId = (String) operation.get('workflowID'); ``` - Build `info.aceOpportunityV2` / `info.createMicrosoftReferralRequest` / `info.gcpOpportunityV2` as nested `Map` 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), call `Suger.CosellApi.updateCosellReferralLinkage(referralId, referralData)` instead — it sends `isLinkageUpdate=true` so the linkage saves even when the referral's partner-opportunity state would fail validation (see [Updating a referral](#updating-a-referral)). - `updateCosellReferral` calls the same `PATCH` endpoint, so it is refused for an AWS referral in `CREATE_FAILED`. To resubmit one, call `Suger.CosellApi.createCosellReferral` with the referral including its `id`. ### 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__c` record. 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. :::note If you don't see the **Referral Payload (JSON)** input in Flow Builder, upgrade the Suger Connector package — it's available in recent versions. `createCosellReferral` itself is `@AuraEnabled` (not `@InvocableMethod`), so it isn't selectable in Flow directly; these two actions are the Flow entry points, or call it from your own Apex as shown above. ::: ## 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")) ``` :::warning **The equality operator is `=`, not `eq`.** Sending `eq` is rejected with `400 invalid operator`. A field name the API does not recognise is rejected with `field not found` — note that this one surfaces as a `500`, not a `400`, so do not rely on the status code alone to tell a bad operator from a bad field name. ::: 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` | **`in` and `not_in` take their values as separate arguments, with no brackets:** ``` q=(in status "ACTIVE" "IN_REVIEW" "ACTION_REQUIRED") ``` Brackets are not list syntax here. `(in status ["ACTIVE" "IN_REVIEW"])` is read as the three values `[ACTIVE`, `IN_REVIEW`, and `]`, so the first value silently never matches and no error tells you so. 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](/api/create-cosell-referral/) (`POST /org/{orgId}/cosell/referral`) in the Fours API reference. The authoritative field definitions for each cloud are the partner references linked above: - [AWS — CreateOpportunity](https://docs.aws.amazon.com/partner-central/latest/APIReference/API_CreateOpportunity.html) - [Microsoft — Create a referral](https://learn.microsoft.com/en-us/partner-center/developer/create-a-referral) - [Google Cloud — opportunities](https://docs.cloud.google.com/channel/docs/reference/rest/v1alpha1/opportunities) --- Source: https://doc.fours.com/cosell/cosell-syncing/ # Referral Syncing Keep your referrals up to date across your CRM and cloud partners — automatically. --- ## Overview After you share an opportunity or accept an inbound referral, Fours keeps that referral **continuously in sync** across three systems — your **CRM** (Salesforce, HubSpot, or Dynamics 365), **Fours**, and the **cloud partner** (AWS, Azure, or GCP) — for the entire life of the deal. A change made in one place is automatically reflected in the others, with no manual re-entry. Syncing runs in the background on a regular schedule, and you can also trigger it on demand. ```d2 direction: down crm: "Your CRM\nSalesforce · HubSpot · Dynamics 365" suger: "Fours\nthe referral record" partner: "Cloud partner\nAWS ACE · Azure · GCP" crm -> suger: "outbound sync\nscheduled every ~6h\n(7-day modified window)" suger -> partner: "outbound push\nsame run" partner -> suger: "inbound sync\nscheduled every ~3h" suger -> crm: "inbound write-back\nsame run" group: "Real-time partner events" { eb: "AWS EventBridge" ps: "GCP Pub/Sub\nCREATED and UPDATED" } eb -> suger: "immediate re-sync" ps -> suger: "immediate re-sync" ``` :::info Syncing is different from **sharing** and **accepting**, which create a referral in the first place. See [Outbound Referral](/cosell/cosell-outbound/) and [Inbound Referral](/cosell/cosell-inbound/) for those steps. This page covers what happens _afterward_ — keeping the referral up to date. ::: ## Where to Find Everything The co-sell page is organized as a row of tabs. What you see depends on which CRMs your organization has connected: | Tab | Contents | | --- | --- | | **Salesforce** | Your Salesforce opportunities and their referrals. Shown when Salesforce is connected. | | **HubSpot** | Your HubSpot deals and their referrals. Shown when HubSpot is connected. | | **Dynamics 365** | Your Dynamics 365 opportunities and their referrals. Shown when Dynamics 365 is connected. | | **Cloud Partners** | Referrals grouped by partner, selected with the chips **AWS · AZURE · GCP · SUGER**. | | **Metrics** | Sync and workflow reporting — see below. | | **Settings** | Your co-sell configuration, in four sub-tabs: **Intelligence**, **Configs**, **Account Mapping**, and **Lead Enrichment** (Lead Enrichment only with a verified Salesforce integration). See [Configuration](/cosell/cosell-configuration/). | One CRM tab appears per connected CRM, so an organization on a single CRM sees one, and an organization on all three sees three. **Cloud Partners** and **Metrics** always follow them, and **Settings** comes last. Co-sell configuration used to live on the console's main **Settings** page; it moved to this tab, and an old `settings?tab=cosell` link still lands on it. An organization with nothing to co-sell yet sees only **Settings**, which is where co-sell is configured. ### Metrics sub-tabs **Metrics** is itself split into three sub-tabs: | Sub-tab | What it shows | | --- | --- | | **Performance** | How your co-sell motion is performing over time. | | **Actions** | Outstanding actions across your referrals. | | **Logs** | The per-run record of every sync and workflow, with status, provider, and timestamp. | Most of the troubleshooting on this page uses **Logs**. ## How Syncing Works Fours syncs referrals in two directions: **Outbound — from your CRM to the cloud partner.** When you update an opportunity/deal in your CRM (for example, the close date, stage, or deal value), Fours pushes those changes out to the cloud partner's co-sell portal. You control exactly which fields are kept in sync from the [Sync Fields](/cosell/cosell-configuration/#sync-fields) configuration. **Inbound — from the cloud partner to your CRM.** When the cloud partner updates a referral on their side (for example, the status changes, a stage advances, or new details are added), Fours pulls those changes back into the matching opportunity/deal in your CRM. Only fields that actually changed are updated. Fours compares the latest values on each side and leaves everything else untouched, so syncing never overwrites unrelated data in your CRM. ## How Often It Syncs Syncing happens automatically in the background: - **Inbound** (partner → CRM) — about every **3 hours**. Partner-side changes are usually picked up much sooner: **AWS** and **GCP** deliver event notifications to Fours (AWS EventBridge, GCP Pub/Sub) that trigger an immediate sync of the affected referral, and Fours additionally polls for new **AWS** and **Azure** referrals about every **10 minutes**. - **GCP Pub/Sub** now processes `CREATED` events as well as `UPDATED`, so a referral Google originates lands in Fours in near real time instead of waiting for the next scheduled run. A **partner-sourced** `CREATED` event is deliberately skipped — it is either your own outbound create still in flight or one made directly in the GCP console — and is picked up by the scheduled inbound sync instead. - **AWS EventBridge** referral events also push the resulting referral straight to the `Suger__Referral__c` mirror in Salesforce, rather than waiting for the next scheduled backfill. - **Outbound** (CRM → partner) — about every **6 hours**. To keep scheduled syncs fast, most of them are **incremental** — each run only looks at what changed recently: - The scheduled **outbound** sync only re-syncs opportunities/deals that your CRM reports as modified within the last **7 days** — based on the record's last-modified timestamp (Salesforce: `SystemModstamp`; HubSpot: `hs_lastmodifieddate`). Exception: if your [Sync Fields](/cosell/cosell-configuration/#sync-fields) configuration was changed within the past **2 days**, the scheduled run performs a **full sync** instead, so the new mappings are applied to every referral. - The scheduled **inbound** sync window depends on the cloud partner: | Partner | Scheduled inbound window | | --- | --- | | **AWS** | Referrals the partner modified within the last **30 days** (based on the ACE opportunity's `LastModifiedDate`). | | **Azure** | Referrals modified within the last **24 hours**. | | **GCP** | Referrals modified within the last **7 days**. The window is deliberately wider than the 3-hour cadence so a missed or failed run heals itself on the next cycle without a manual full sync. | A [manual sync](#run-a-sync-manually) has no such window — it re-syncs everything. ### The dates on a referral are the partner's dates **Created Date** and **Last Modified** on the referrals table show the **partner's own timestamps** — what AWS ACE, Microsoft Partner Center and the GCP console show for the same opportunity — not when Fours happened to write the row. A Fours-internal referral has no partner side, so those rows fall back to Fours' own timestamp. Sorting and filtering follow the same rule, so a descending sort no longer floats rows with no partner date to the top. The same rule applies in the Console, the [Salesforce referral table](/salesforce-app/salesforce-app-cosell/), and the HubSpot deal card. ## Run a Sync Manually You don't have to wait for the next scheduled sync. From the co-sell referrals table, open **More actions** — the one dropdown that now holds all three bulk operations: - **Inbound Sync** — pull the latest referrals and updates from a cloud partner into Fours. Use this if a referral is missing or seems delayed. - **Outbound Sync** — push your CRM opportunities to the cloud partner's co-sell portal right away. - **Bulk link opportunities** — *Match referrals to Salesforce / HubSpot.* Matches many referrals to CRM records in one background job, rather than opening each referral and linking it by hand. (Per-referral linking is still available on the lead detail page — see [Leads](/cosell/cosell-leads/).) It matches **AWS** referrals only, so the option is listed only while the table is filtered to **AWS**. Anyone who can view and edit co-sell referrals can run it. The menu hides any option your integrations do not support, and does not render at all when none of the three apply. Unlike the scheduled sync, a manual sync is a **full sync**: it re-reads the current CRM values of every active referral, with no recent-change window. This makes it the way to push changes the scheduled sync can't detect — such as formula field updates (see [Troubleshooting](#troubleshooting)). Each sync option lets you choose the cloud partner (AWS, Azure, or GCP). Once a sync starts, Fours runs it in the background. **A manual GCP inbound sync takes precedence.** Because the scheduled GCP inbound sync is incremental, a manual full sync is the only thing that reaches an opportunity that fell outside the 7-day window — so it is exactly the lever to pull when something is missing. If a scheduled run is already in flight for your organization, the manual full sync **replaces** it rather than being dropped. Nothing is lost: a full sync covers everything the replaced run would have, and the schedule resumes on its next tick. **AWS leads sync separately.** Leads have their own inbound sync — a manual full sync from the lead table, and a scheduled run every 3 hours, offset from the referral sync. See [AWS Partner Central Leads](/cosell/cosell-leads/). :::note **Fours partner-to-partner referrals are excluded from Inbound Sync.** A `SUGER` referral has no external partner system to pull from — Fours already holds both companies' copies and keeps them in step itself — so it never appears as an Inbound Sync option. ::: You can check the status of any sync — automatic or manual — in the **Logs** table under **Metrics → Logs**. Set the **Workflow Type** filter to **Sync** for per-referral sync runs, or **Batch Sync** for the scheduled and manually triggered batch runs that process many referrals at once. Each entry shows the run's status (such as _Completed_ or _Failed_), provider, and timestamp. Set **Workflow Type** to **Auto-accept** to see one run for each AWS or Azure [auto-accept](/cosell/cosell-configuration/#auto-accept-referrals) Fours attempted on an eligible referral; **All** includes these runs too, and searching a referral's name or ID finds them. An AWS accept that errors fails its run and is not retried. ## What Gets Synced - **Referral fields** — the fields you configured under [Sync Fields](/cosell/cosell-configuration/#sync-fields) (outbound) and your inbound field mappings. - **Status & stage** — the partner's status and stage are mapped to Fours' unified status. See [Status & Stage](/cosell/cosell-status/). - **Contacts** — customer contact details are synced into your CRM. For AWS, contact information is shared 10–30 minutes after a referral is accepted; see [Inbound Referral](/cosell/cosell-inbound/). Referrals in an inactive state — Draft, Rejected, Expired, or Deleted — are not synced in either direction. Closed referrals (Closed Won / Closed Lost / Closed Error) are no longer pushed **outbound**, but they still receive **inbound** updates from the cloud partner. ## Troubleshooting **My change hasn't appeared yet.** Automatic sync runs every few hours. If you need it sooner, run a manual sync. **A formula (calculated) field changed in my CRM but never synced.** Salesforce computes formula fields at read time — when a formula's inputs change (for example, a field on the related Account), the opportunity record itself is not modified, so Salesforce [does not update its last-modified timestamp](https://help.salesforce.com/s/articleView?id=005239151&language=en_US&type=1). The scheduled outbound sync relies on that timestamp to detect changes, so formula-only updates are invisible to it — the partner side keeps the old value. To fix: run a manual **Outbound Sync** (a full sync that reads the current formula values), or add a Salesforce Flow that touches the opportunity whenever the formula's inputs change so the scheduled sync picks it up. **A field changed back to a different value.** When the same field is updated in both your CRM and the partner portal between syncs, the most recent change wins. If a field shouldn't be synced at all, adjust your [Sync Fields](/cosell/cosell-configuration/#sync-fields) configuration. **A referral shows "Update Failed".** Hover over the status to see the error message, fix the underlying data, and the next sync will retry. See [Status & Stage](/cosell/cosell-status/) for error troubleshooting. **A CRM change never reached AWS, and the referral shows a red !.** This applies to AWS referrals that AWS has approved or sent back as Action Required. Before pushing a CRM change to AWS, Fours checks it against AWS's update rules for the opportunity's stage. A change that fails the check is skipped: the referral's status and data stay as they were, and a red **!** appears on its status tag, with a reason that starts with `CRM sync rejected:`. Hover over the tag to read it, or open the referral, where the same reason appears in the banner at the top of the page. For example, from *Committed* onwards AWS no longer accepts "Other" as the solution, so moving the deal to *Launched* while "Other" is its only solution is rejected with *Once the opportunity reaches Committed stage or beyond, 'Other' is no longer accepted — please select a valid solution identifier.* To fix it, correct the field in your CRM. The next scheduled outbound sync, or a manual **Outbound Sync**, re-checks the record, pushes the change, and clears the red **!**. ```d2 direction: down change: "CRM change" check: "Passes Fours' AWS\nupdate check?" { shape: diamond } push: "Pushed to AWS" skip: "Change skipped\nstatus and data unchanged\nred ! with CRM sync rejected: reason" fix: "Correct the field in your CRM" change -> check check -> push: "yes" check -> skip: "no" skip -> fix fix -> check: "next outbound sync" ``` **My CRM deal is Closed Won, but the Fours co-sell is still open.** Fours tried to close the Fours partner-to-partner co-sell as Won, and one of the Close Won checks blocked it. The co-sell's detail page names the reason. See [CRM Closed Won didn't close the co-sell](/cosell/cosell-status/#crm-closed-won-didnt-close-the-co-sell). --- Source: https://doc.fours.com/cosell/cosell-mcp/ # Co-Sell with AI (MCP) Run the full co-sell referral lifecycle from your AI assistant, using natural language --- ## Overview The [Fours MCP Server](/mcp/overview/) exposes Fours' co-sell APIs as tools that any [Model Context Protocol](https://modelcontextprotocol.io/) client — Claude Desktop, Claude Code, Cursor, VS Code (GitHub Copilot), Windsurf, ChatGPT — can call. Instead of clicking through the Fours Console, a Partner or Alliance Manager can describe what they want in plain language and let the assistant create referrals, look up status, sync with the cloud partner, and read dashboard insights. One connection covers **AWS, Azure, and GCP** co-sell, plus peer-to-peer co-sell with the partner companies you work with through Fours. The destination is chosen per call by the `partner` field: `AWS` / `AZURE` / `GCP` share the opportunity with that cloud provider, and `SUGER` shares it with another company you partner with through Fours. **Availability:** All Fours pricing plans **MCP Server URL:** `https://apiv2.suger.cloud/mcp` See [MCP → Setup](/mcp/setup/) to connect your client, and [MCP → Overview](/mcp/overview/) for the full tool catalog and security model. **Prerequisite:** your organization's co-sell integration must already be connected — see [Co-Sell Configuration](/cosell/cosell-configuration/). ## Co-Sell tools The MCP server exposes 19 co-sell tools, covering the whole referral lifecycle: | Tool | What it does | |------|--------------| | `ListCosellReferrals` | List referrals (inbound + outbound) with filters — partner, status, stage, time range, text | | `GetCosellReferral` | Get the full record for one referral by ID | | `CreateCosellReferral` | Create an outbound referral to a cloud provider (AWS / AZURE / GCP) or to a partner company (SUGER) | | `RegisterCosellOnBehalf` | Register a co-sell referral on behalf of another company you partner with | | `UpdateCosellReferral` | Edit referral fields, status, or stage — and, on a referral a partner shared with you, accept or decline it | | `BatchCreateCosellReferrals` | Create several referrals in one call (recommended ≤ 20) | | `BatchPreviewCosellReferrals` | Preview the referrals that would be created from CRM records, before creating them | | `ValidateReferral` | Dry-run validate a referral against the partner schema **before** creating it | | `PredictReferralQualityScore` | Predict the AWS opportunity quality score for a referral | | `SyncSingleReferral` | Sync one referral inbound or outbound with the cloud partner; on a `SUGER` referral this syncs the linked CRM record instead | | `AzureInvitePartnerCollaboration` | Invite another partner to collaborate on an Azure referral (Azure only) | | `AzureMicrosoftSolutionLookup` | Look up a Microsoft first-party solution to attach to an Azure referral (Azure only) | | `AzureThirdPartySolutionLookup` | Look up a third-party (marketplace) solution to attach to an Azure referral (Azure only) | | `GetCosellDashboard` | Co-sell insights — pipeline KPIs, outstanding actions, activity logs | | `GetPartnerContacts` | List known partner contacts for a buyer company (by email domain) | | `SearchPartnerConnections` | Search the org's connected AWS partners. A query matches a partner's name or its AWS account ID, although the tool's own description mentions only the name | | `UpdateCosellPartner` | Seller-only. Update one partner's copy of a `SUGER` co-sell — revenue-share terms (before Close Won), deal-value visibility, and collaboration fields | | `ProposeCommissionUpdate` | Seller-only. Request a change to a partner's commission terms *after* Close Won; the change needs that partner's approval | | `UpdateCommissionLifecycle` | Advance a `SUGER` co-sell's commission to its next state once the deal is Won | The descriptions above are deliberately short. For each tool's full parameter list and response shape, see [MCP → Supported Tools](/mcp/tools/). :::note `BatchPreviewCosellReferrals` and `PredictReferralQualityScore` call a language model and record AI usage for your organization, so each call has a cost. ::: ### What `ValidateReferral` returns Two behaviours are worth knowing before you build a workflow on the dry run: - **Duplicate open referrals come back as a warning.** If the same partner already has a still-open referral matching the one you are validating, `ValidateReferral` reports it. It is advisory — the create call is not blocked, because two referrals can legitimately exist for the same customer. - **`partner=SUGER` is rejected.** Validation covers **AWS, GCP, and Azure** only. Asking the assistant to validate a Fours partner-to-partner referral returns an error rather than a result — skip validation and call `CreateCosellReferral` directly for `SUGER`. ### Fours peer-to-peer referrals (`partner=SUGER`) A `SUGER` referral is shared with another company you partner with through Fours, not with a cloud provider. It behaves differently in four ways worth knowing before you prompt for one: - **The partner responds in Fours.** The recipient gets their own copy in `PENDING_ACCEPTANCE`. They accept by moving it to `ACTIVE`, or decline by setting `status` to `REJECTED` with a `declineReason` (required — the request is refused without it). Only the company that *received* the referral can respond; the sender withdraws instead. Both use `UpdateCosellReferral`. - **No outbound sync is needed.** There is no external partner system to push to — Fours keeps the partner's copy in step itself. `SyncSingleReferral` on a `SUGER` referral synchronizes the linked **CRM** record, accepts `direction=OUTBOUND` only, and returns an error for `INBOUND`. - **Send only the fields you are changing.** On a partner's copy whose deal value is hidden, a read returns `dealValueAmount`, `dealValueCurrency` and `sharePercentage` blanked out. Reading a referral and sending the whole object back writes those blanks or fails validation — so ask the assistant to patch specific fields rather than echo a record back. - **Won needs an accepted co-sell.** A `SUGER` co-sell can move to stage `Won` only once its status is `ACTIVE`. Before it has been accepted, the update is refused with `cannot close as Won from status "…"; the co-sell must be Active (accepted) first`. Use `ListPrmPartners` (see [MCP → Supported Tools](/mcp/tools/)) to find the partner and get the `partnerId` a `SUGER` referral needs. #### Commission tools Three of the tools above apply only to `SUGER` referrals, and only after the deal is Won. `UpdateCommissionLifecycle` advances a commission by naming the **target state** you want; the action is derived from the current and target pair. Only four states can be named as a target, and only from the state that legitimately precedes them: | From | Target `state` | What it means | | --- | --- | --- | | `PENDING` | `APPROVED` | The commission terms are agreed. | | `APPROVED` | `PAYMENT_SENT` | Payment has been sent to the partner. | | `PAYMENT_SENT` | `CONFIRMED` | The partner confirmed receipt. | | `PAYMENT_SENT` | `APPROVED` | The partner **rejected** the payment, sending it back for another attempt. | | `CONFIRMED` | `CLAWED_BACK` | The commission has been reversed after receipt was confirmed. | Any other pair is refused with `INVALID_TRANSITION`. :::warning **Do not send `PAYMENT_REJECTED` as a target.** It is a state the server writes for you: rejecting a payment is expressed as `PAYMENT_SENT → APPROVED`, and the server records the rejection and the revert as two history entries in one write. The same is true of `PENDING` and `PENDING_UPDATE_APPROVAL` — they are states you can observe, never states you can ask for. ::: The commission lives on the **payee** (reseller) copy, which the server resolves for you — you always pass your *own* `referralId`. A **Seller** must additionally send `partnerOrganizationId` to say whose commission is being acted on; a partner acting on its own commission omits it. To change the commission *terms* rather than advance the state, use `ProposeCommissionUpdate`. That is a Seller-only request that needs the partner's approval, which the partner gives back through `UpdateCommissionLifecycle`. :::note Destructive or org-wide operations are intentionally **not** exposed to AI — deleting a referral, bulk-syncing an entire org, auto-share, and system-config endpoints must be done in the Fours Console. Co-sell **funding** applications are managed in the Console and API (see [Co-Sell Funding](/cosell/cosell-funding/)); they are not available as MCP tools. ::: ## Example prompts - **List:** "List my AWS referrals in Pending Acceptance status from last week." - **Detail:** "Show me referral `ref-abc123`." - **Create:** "Create an AWS co-sell referral for Acme Corp, expected close date 2026-09-30." - **Validate first:** "Validate this referral against the AWS schema before I submit it." - **Update status / stage:** "Move referral `ref-abc123` from Draft to Submitted." - **Sync:** "Sync referral `ref-abc123` outbound to AWS." - **Insights:** "Show my co-sell pipeline for the last 30 days." - **Partner lookup:** "Who at AWS have we worked with for acme.com before?" - **Share with a partner company:** "Share the Acme deal with Contoso as a Fours co-sell referral." - **Respond to a partner:** "Accept the referral Contoso shared with us." ## Recommended workflow 1. **Validate before you create.** Ask the assistant to run `ValidateReferral` first — each cloud partner requires different fields, and a dry run surfaces missing values before anything is sent. This step applies to **AWS, GCP and Azure** only; `partner=SUGER` is rejected by validation, so go straight to `CreateCosellReferral` for a partner-to-partner referral. 2. **Create the referral.** On a successful create the referral is submitted to the partner automatically; its status becomes `PENDING_CREATE` (or `CREATE_FAILED` if the partner API rejects it — to retry, fetch it with `GetCosellReferral`, fix the fields, and call `CreateCosellReferral` again with the same `id`). If your organization has the co-sell approval process enabled, a brand-new referral is instead saved as `DRAFT` and is not submitted until it is approved in the Fours Console. 3. **Track and update.** Use `ListCosellReferrals` / `GetCosellReferral` to check progress, and `UpdateCosellReferral` to edit fields or move status / stage. 4. **Let updates push themselves.** For AWS / Azure / GCP, a successful `UpdateCosellReferral` starts the outbound sync to the cloud partner by itself — don't call `SyncSingleReferral` afterwards. Two updates are saved but not sent: with the co-sell approval process on, an update to a referral that isn't approved or submitted yet stays a `DRAFT` until it is approved in the Fours Console, and an update to an AWS referral at `Launched` or `Closed Lost` stays in Fours. Use `SyncSingleReferral` to pull the latest partner state. A `SUGER` referral needs no sync either — Fours propagates the partner's copy itself, and `SyncSingleReferral` there syncs the linked CRM record instead. ## Security & scope - **Authentication:** OAuth 2.1 only (API keys and static tokens are not supported for MCP). - **Organization scoping:** every tool call is scoped to your authenticated organization — there is no way to reach another organization's referrals. - **Permissions:** the MCP server respects your existing Fours co-sell permissions (read / create / edit). It never grants access broader than your account already has. ## Troubleshooting | Issue | Possible cause | Resolution | |-------|----------------|------------| | Referral stuck in `CREATE_FAILED` | The partner API rejected one or more required fields | Fetch it with `GetCosellReferral`, fix the fields, and call `CreateCosellReferral` again with the same `id` — Fours resubmits that referral in place. Without the `id` you get a second referral. Run `ValidateReferral` first next time to catch this before creating. | | `UpdateCosellReferral` is refused on an AWS referral in `CREATE_FAILED` | AWS never accepted a referral whose create failed, so it can only be resubmitted, not edited | Fetch it with `GetCosellReferral` and call `CreateCosellReferral` again with the same `id`. | | Referral saved as `DRAFT` instead of submitting | Your organization has the co-sell approval process enabled | Approve the referral in the Fours Console — it will not submit automatically. | | Changes aren't showing up on the cloud partner's side | The update is waiting for approval (the co-sell approval process is on), or the AWS referral is already `Launched` or `Closed Lost`, whose content Fours no longer sends | Approve the referral in the Fours Console. Otherwise the outbound sync starts on its own after `UpdateCosellReferral` — don't call `SyncSingleReferral` to push it. Not applicable to `SUGER` referrals — Fours propagates those itself. | | `SyncSingleReferral` fails on a `SUGER` referral with `direction=INBOUND` | On a `SUGER` referral this tool syncs the linked CRM record, which is outbound-only | Call it with `direction=OUTBOUND`, or skip it — the partner's copy is already in step. | | Declining a `SUGER` referral is rejected | `declineReason` is required when setting `status` to `REJECTED` | Supply a reason, e.g. "Decline referral ref-abc123 because the budget was cut." | | `ValidateReferral` errors on a `SUGER` referral | Validation supports AWS, GCP and Azure only | Skip the dry run and call `CreateCosellReferral` directly for `partner=SUGER`. | | Validation warns about a duplicate open referral | The partner already has a still-open referral matching this one | Advisory only. Check whether it really is a duplicate, then create anyway if the new referral is distinct. | | Can't delete a referral or bulk-sync the whole org from chat | Destructive and org-wide operations are intentionally excluded from MCP tools | Use the Fours Console for deletes, bulk-sync, or auto-share. | | Can't submit a funding application from chat | Co-sell funding is not available as an MCP tool | Use the Fours Console or API — see [Co-Sell Funding](/cosell/cosell-funding/). | ## FAQ **Can I manage co-sell funding requests through MCP?** No — funding applications are managed in the Fours Console and API only. See [Co-Sell Funding](/cosell/cosell-funding/). **Can my AI assistant delete a referral or sync my whole organization at once?** No. Destructive and org-wide operations are intentionally excluded from MCP tools. Use the Fours Console for these. **What happens right after I create a referral?** It submits to the cloud partner automatically and its status becomes `PENDING_CREATE` (or `CREATE_FAILED` if the partner rejects it — fetch it with `GetCosellReferral`, fix the fields, and call `CreateCosellReferral` again with the same `id`). If your organization has co-sell approval enabled, it is saved as `DRAFT` until approved in the Console instead. **Does updating a referral in chat also update it with the cloud partner?** Yes, for AWS, Azure and GCP. A successful `UpdateCosellReferral` starts the outbound sync on its own, so don't call `SyncSingleReferral` afterwards. The exceptions: an update saved as a `DRAFT` under the co-sell approval process waits for approval in the Console, and an update to an AWS referral at `Launched` or `Closed Lost` stays in Fours. A `SUGER` referral has no external partner system, and Fours keeps the partner's copy in step itself. **Can I share a deal with another Fours partner company, not a cloud provider?** Yes — create the referral with `partner=SUGER` and the partnership's `partnerId`. The partner receives their own copy and accepts or declines it in Fours. See [Fours peer-to-peer referrals](#fours-peer-to-peer-referrals-partnersuger) above. For the developer view of the same create endpoint, see [Create a Referral via API](/cosell/cosell-referral-api/). --- Source: https://doc.fours.com/cosell/cosell-ace-fields/ # Co-Sell Fields in ACE A reference for the AWS ACE fields you map and submit when co-selling opportunities through Fours. --- ## Overview ACE stands for the **APN (AWS Partner Network) Customer Engagements** program. It helps AWS partners collaborate with AWS to sell their solutions together. The fields on this page are part of that sales collaboration process. When you share an opportunity with AWS, you need to include the mandatory information AWS requires, and you can add optional details as needed. To control how these fields are pre-filled from your CRM, see [Field Mapping](/cosell/cosell-configuration/) in the Co-Sell configuration guide. ## Field Mapping Best Practices When you set up Field Mapping, keep the following in mind so data flows accurately between your CRM and ACE. - **Customer Name** — Map to your CRM's Account Name. - **Estimated AWS Monthly Revenue** — If your CRM only tracks yearly revenue (for example, in the `Amount` field), use an expression to convert it. A typical estimate uses `Amount * 0.025`. Click **Formula** on the row, then either build it on **Build** with the **Transform a field** recipe (*Amount*, *multiplied by* `0.025`) or write it on **Code**: `{{- multiply .Amount 0.025 -}}`. - **Industry** — Map to your account's industry field. Use the **AI Generate** feature to auto-match your CRM values with ACE's expected values. - **Customer Website** — Map to your Account Website. - **Partner Project Title** — Usually maps to the Opportunity Name field. - **Customer Business Problem** — Map to a specific field if you have one, use a default value, or use **AI Generate** to draft it from your CRM data. AWS expects a detailed description here; when you use AI Generate, Fours automatically instructs the AI to produce 500–1,800 characters and truncates anything over 1,800. - **Target Close Date** — Map to your CRM's Close Date. - **Stage** — Map to your CRM stage field, then align all stage values manually to their ACE equivalents (for example, Closed Lost, Qualified). - **Delivery Model** — Use a default such as SaaS or PaaS. - **Opportunity Type** — If not available, default to "Net New Business." If available, map values like Expansion, Renewal, and Net New accordingly. - **Partner Primary Need from AWS** — Use the default value "Co-Sell Deal Support." - **Sales Activities** — Optional; a default is sufficient in most cases. - **Solutions Offered** — This field might not appear initially. Scroll to the bottom, choose **Add Field** to add it manually, then use a default or mapped value. - **Use Case** — Use a default value unless your CRM contains this data. - **Address Fields (City, State, Country, Postal Code)** — Use billing or shipping address fields based on your preference. - **Primary Contact (Name, Email, Phone)** — Optional; map to your internal primary contact if desired. These fields are not required for AWS submission. :::tip For conditional logic, value conversions, and calculations like the AWS MRR estimate above, use **Formula** (Expression Mode). To align picklist values (for example, Stage and Industry) between your CRM and ACE, use Picklist Value Mapping — the **Picklist** recipe inside **Formula**. Both are covered in [Configuration](/cosell/cosell-configuration/#expression-mode). ::: ## Customer Information | Field | AWS Description | Status | | --- | --- | --- | | Customer Company Name | Specifies the end customer company name. | Mandatory | | Customer Website | Specifies the end customer website. | Mandatory | | Industry | Specifies the industry of the end customer. | Mandatory | | Country | Specifies the country where the end customer is based. | Mandatory | | Postal Code | Specifies the postal or ZIP code corresponding to the end customer's business address. This is crucial for geo-mapping the company. | Mandatory | ## Project Information | Field | AWS Description | Status | | --- | --- | --- | | Opportunity Type | Indicates whether the opportunity is a Net New Business, a Flat Renewal, or an Expansion. | Mandatory | | Partner Project Title | Identifies the opportunity name. | Mandatory | | Customer Business Problem | Describes the problem the end customer is facing and how the partner is helping with a solution. | Mandatory | | Sales Activities | Specifies the sales activities conducted with the end customer that relate to the opportunity. | Mandatory | | Partner Primary Need from AWS | Identifies the help required from AWS for the opportunity. | Mandatory | | Delivery Model | Specifies the delivery model of your solution (SaaS or PaaS, Professional Services, etc.). | Mandatory | | Solution Offered | Links solutions or offerings to the opportunity. Insert the Offering IDs associated with the solutions being evaluated to address the customer's business problem. When an Offering ID isn't available, enter "Other" and provide details in the Other Solution Offered field. Offering IDs are found in AWS Partner Central > Build > Offering > Offering Detail Page and follow the `S-1234567` pattern. | Mandatory | | Use Case | Specifies the use case of the end customer that the opportunity is intended to address. | Mandatory | | Expected Monthly AWS Revenue | The amount of revenue you expect the opportunity to generate for AWS. | Mandatory | | Target Close Date | Indicates the date you expect the deal to close. | Mandatory | | Is Opportunity from Marketing Activity? | A Yes or No field. | Mandatory | | Rejection Reason | Specifies the reason for rejecting an AWS referral. AWS uses this to derive insights into why the opportunity was rejected. | Conditionally Mandatory | | Parent Opportunity ID | Specifies the `apnCrmUniqueIdentifier` of the parent opportunity associated with the current opportunity. | Conditionally Mandatory | | Other Solution Offered | Specifies the solution offered to solve the customer's business problem when the Solution Offered field is set to "Other". | Conditionally Mandatory | | Does this opportunity contain classified National Security information? | Indicates whether the opportunity belongs to the national security category. | Optional | | Customer Data Universal Number System (DUNS) | Specifies the Data Universal Numbering System (DUNS) that uniquely identifies a customer. The DUNS is a nine-digit identification number issued by Dun & Bradstreet (D&B). Each DUNS number is specific to a particular site, so separate numbers may be assigned to distinct physical locations of an entity, including branches, divisions, and headquarters. | Optional | | AWS Products | Associates specific AWS products with the opportunity. Partners can indicate which AWS products are relevant to the opportunity's solution and align with the customer's needs. | Optional | | Partner Contact Title | Job title or role of the partner's sales contact person associated with the opportunity. | Optional | | Offer ID | Specifies the identifier of the AWS Marketplace Private Offer associated with this opportunity. | Optional | | APN Programs | Specifies the APN (Amazon Partner Network) Program that influenced the opportunity. APN Programs are specific partner programs or initiatives that can impact the opportunity. | Optional | | AWS Marketplace Engagement Score | Displays an estimate (High, Medium, or Low) of how likely the customer in an opportunity is to procure a solution through AWS Marketplace. Opportunities without a score don't yet have enough customer information to determine a Co-Sell score; the score surfaces once enough information is available. | Read Only | | AWS Recommended Action | Indicates the recommended next best actions for the opportunity, offering insights and guidance on the optimal steps to progress it. These recommendations are based on the current status, context, and available data associated with the opportunity. | Read Only | ## Picklist Reference AWS accepts only its own values in these fields. Use the lists below when you set up **Picklist Value Mapping** — every active CRM value you send has to land on one of these, or the submission fails. ### Customer fields **Industry** — 28 values: | 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 fields **Opportunity Type** — 3 values: | Opportunity Type | | --- | | Flat Renewal | | Expansion | | Net New Business | **Delivery Model** — 6 values. This field accepts multiple selections: | Delivery Model | | --- | | SaaS or PaaS | | BYOL or AMI | | Managed Services | | Professional Services | | Resell | | Other | **Sales Activities** — 8 values. This field accepts multiple selections: | Sales Activities | | --- | | 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 | **Partner Primary Need from AWS** — a two-level field. First choose the top-level answer: | Top-level choice | What it means | | --- | --- | | **Co-Sell with AWS** | You want AWS involved, and you then pick one or more detail values below. | | **Do Not Need Support from AWS Sales Rep** | Visibility only — no detail value is needed. | When you choose **Co-Sell with AWS**, pick from these 8 detail values (multiple selections allowed): | Detail value | | --- | | 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 | **APN Programs** — 18 values. This field accepts multiple selections: | APN Program | Selectable outbound? | | --- | --- | | APN Immersion Days | Yes | | APN Solution Space | Yes | | ATO (Authority to Operate) | Yes | | AWS Marketplace Campaign | Yes | | Cloud Adoption Framework Program (CAF) | Yes | | ISV Immersion Day SFID Program | Yes | | ISV Workload Migration | Yes | | Migration Acceleration Program | Yes | | Model Provider PARC | **No — inbound only** | | P3 | Yes | | Partner Launch Initiative | Yes | | Partner Opportunity Acceleration Funded | Yes | | The Next Smart | Yes | | VMware Cloud on AWS | Yes | | Well-Architected | Yes | | Windows | Yes | | Workspaces/AppStream Accelerator Program | Yes | | WWPS NDPP | Yes | :::warning **Model Provider PARC is inbound-only.** AWS rejects it on a partner-originated opportunity — `ValidationException: APN Programs: Model Provider PARC is not valid for partner-originated opportunities` — so only **17** of the 18 values are selectable when you create or share a referral outbound. On a partner-originated submission Fours strips the value rather than letting it fail at AWS. It stays fully visible and editable when you **update** an opportunity **AWS originated**: those do carry it, and you can clear it and set it again there. The test is the opportunity's **Origin** (`AWS Referral`), not the referral's inbound/outbound direction — the two are separate fields and can disagree. Because the strip above keys on the same `Origin`, a *create* that carries `Origin: "AWS Referral"` is **not** stripped and will be rejected by AWS; only send the program on an update. ::: :::note **Clearing APN Programs.** Sending an explicit empty list clears the field. **Omitting** the key leaves whatever AWS already has untouched. The two are not the same — if you mean to remove the last remaining program, you must send an empty list rather than dropping the field from the request. ::: ### Competitive and outcome fields **Competitive Tracking** — 11 values: | Competitive Tracking | | --- | | Oracle Cloud | | On-Prem | | Co-location | | Akamai | | AliCloud | | Google Cloud Platform | | IBM Softlayer | | Microsoft Azure | | Other- Cost Optimization | | No Competition | | *Other | **Closed Lost Reason** — 19 values: | Closed Lost Reason | | --- | | Customer Deficiency | | Delay / Cancellation of Project | | Legal / Tax / Regulatory | | Lost to Competitor – Google | | Lost to Competitor – Microsoft | | Lost to Competitor – SoftLayer | | Lost to Competitor – VMWare | | Lost to Competitor – Other | | No Opportunity | | On Premises Deployment | | Partner Gap | | Price | | Security / Compliance | | Technical Limitations | | Customer Experience | | Other | | People/Relationship/Governance | | Product/Technology | | Financial/Commercial | ## Conditional Fields Four fields appear only once another field is set a particular way. If you map them unconditionally you will see them sitting empty most of the time — that is expected. | Field | Appears when | What to enter | | --- | --- | --- | | **Industry Other** | **Industry** is set to `Other` | Free text naming the customer's actual industry. | | **Does this opportunity contain classified National Security information?** | **Industry** is set to `Government` | `Yes` or `No`. | | **Other Solution Offered** | **Solution Offered** is set to `Other` | Free text describing the solution, when you have no `S-1234567` Offering ID. | | **Competitive Tracking Other** | **Competitive Tracking** is set to `*Other` | Free text naming the competitor. | ## Editing a Referral in Action Required When AWS moves a referral to **Action Required**, the referral is locked down to the fields AWS expects you to correct. Only these **9** fields stay editable: | Editable field | | --- | | Customer Address — City | | Customer Address — Country | | Customer Address — Postal Code | | Customer Address — State or Region | | Customer Address — Street Address | | Customer Website | | Target Close Date | | Expected Customer Spend — Amount | | Customer Business Problem | Everything else on the referral is read-only until the referral leaves Action Required. If AWS is asking for a change to a field outside this list, the change has to happen in AWS Partner Central. ### Customer Business Problem after approval **Customer Business Problem** is not only an Action Required field — it stays editable once AWS has **approved** the referral, so you can keep the problem statement current as the deal develops. Two rules govern what AWS accepts: | Rule | Behaviour | | --- | --- | | **Minimum 20 characters** | A shorter value is **silently ignored** — the update succeeds, but AWS keeps the previous text. No error is returned, so check the field afterwards. | | **Maximum 2,000 characters** | A longer value is accepted and **truncated** to 2,000 characters. | ## Partner and Cloud Contacts The ACE referral detail page has a **Contact** tab. It opens with the **Customer contacts** on the opportunity, then separates the two sides of the partnership: | Group | Who is in it | Editable? | | --- | --- | --- | | **Cloud contacts (AWS)** | The AWS-side people on the opportunity — the partner sales rep and the rest of the AWS team. | No — AWS owns this roster. | | **ISV contacts** | Your own people, carried on the opportunity team. | Yes, per row, when the conditions below are met. | ### Editing your ISV contacts AWS accepts exactly two partner-contact roles, and one contact per role: | AWS role | Shown as | | --- | --- | | `PartnerAccountManager` | **Partner Account Manager** | | `OpportunityOwner` | **Partner Opportunity Owner** | Each ISV contact row has its own **Edit** button. You can change: - **First name** and **last name** — up to 80 characters each - **Email address** - **Phone number** **Business Title is never editable.** It is the role itself, and it is what AWS matches the contact on — so a role can be filled or corrected, but never renamed or re-assigned. Leaving a field **blank keeps the value AWS currently holds** rather than clearing it; AWS requires a name and an email on every assignee, so a contact can be changed but not emptied. :::note **When editing is available.** ISV contacts are editable only while AWS will still accept the change — that is, when the referral's review status is **Approved** *and* its stage is **not** `Launched` or `Closed Lost`. Outside that window the Edit buttons do not appear, because an edit would be stored in Fours and never reach AWS. ::: If AWS rejects the assignment, the failure is reported with the contact that caused it, in the form `failed to assign partner contacts: (): `. ## AWS Marketplace Transactions The ACE referral detail page has an **AWS Marketplace transactions** tab that ties the referral to the private offer the deal actually transacts through. From that tab you can: - **Link Offer** — attach an AWS Marketplace offer to this referral. - **Unlink Offer** — detach the currently linked offer. :::note Only **accepted AWS contract offers** can be linked. An offer that has not been accepted by the buyer, or that is not an AWS contract offer, does not appear in the picker. ::: ![The AWS Marketplace transactions tab on an ACE referral — the AWS Marketplace offer card with the linked offer's ID, name and created/expiry dates and an Unlink Offer action in its header, and the AWS Marketplace agreement table below listing the agreement that came from that offer](images/61-ace-transactions.png) --- Source: https://doc.fours.com/cosell/cosell-ace-eligibility/ # ACE Eligibility Become ACE eligible so you can co-sell with AWS and receive referrals through the APN Customer Engagement (ACE) Program. --- ## Overview The **AWS Partner Network (APN) Customer Engagement (ACE) Program** helps AWS Partners support customers and drive successful engagements on AWS. Qualifying partners who have demonstrated their ability to drive customer engagements on AWS become eligible to receive: - **Leads** — referrals of inbound prospects generated by AWS. - **Opportunities** — pre-qualified opportunities with AWS customers or potential AWS customers. The ACE Program also gives AWS Partners access to sales opportunities, funding options, and more. The goal for co-selling with AWS is to get into ISV Accelerate, which can open up new opportunities and strengthen your partnership with AWS. ### Check whether you are already ACE eligible If you believe you are already ACE eligible, you can verify it: 1. Sign in to [AWS Partner Central](https://partnercentral.awspartner.com/partnercentral2/s/). 2. Scroll to the **AWS Partner Paths** section. 3. Confirm that your Software Path is **Validated** and shows a Solution with an approved FTR. If you are not ACE eligible yet, follow the steps below. ![ACE eligibility overview in AWS Partner Central](images/ace-eligibility-1.png) ## Necessary Team Members During the process, the following roles are crucial: - **APN Admin** — logs in to AWS Partner Central and grants permission to the necessary team members. - **Technical Manager** — provides information for the Foundational Technical Review (FTR) and submits it. - **Sales team member** — provides information about the opportunities submitted for validation in AWS Partner Central. ## Steps to Become ACE Eligible ### Step 1: Join the AWS Partner Network (APN) Create an AWS Partner Network (APN) account. Make sure the Alliance lead is the person creating this account — the Alliance lead will be the primary owner of the APN account. ### Step 2: Enroll in the AWS Software Partner Path Once registered with the AWS Partner Network, enroll in the **Software Partner Path**. ### Step 3: Create a Partner Solutions Finder listing Create your listing through **AWS Partner Central → My Company → Company Profile**. ### Step 4: Accept ACE terms and conditions You must accept the AWS terms and conditions to co-sell with AWS and access APN programs and benefits: 1. Navigate to the **Home** page in AWS Partner Central and scroll down. 2. Review and accept the terms when prompted. You can review the terms in advance at [AWS Partner terms and conditions](https://aws.amazon.com/partners/terms-and-conditions/). ### Step 5: Pay the APN membership fee Pay the [APN Program fee](https://partnercentral.awspartner.com/knowledgebase/articles/FAQ/How-Do-I-Pay-the-APN-Program-Fee) via your company's designated AWS account. :::info AWS accounts and AWS Partner Central accounts are separate and may require different login credentials. ::: 1. Log in to your company's AWS account **Billing and Cost Management** console. 2. In the navigation panel, choose **Payments**. 3. In the **Payments due** table, select the invoice you want to pay and choose **Complete payment**. 4. On the Complete a Payment page, your default payment method is selected if it is eligible to pay the invoice. 5. To use a different payment method or choose an eligible one, choose **Change**. 6. Confirm that the summary matches what you want to pay, and choose **Verify and pay**. 7. After your bank processes the payment, you are redirected to the Payments page. ### Step 6: Share at least 10 sales opportunities All AWS Partners must submit at least 10 opportunities and get them validated by the AWS team. Follow these steps: 1. Log in to [AWS Partner Central](https://partnercentral.awspartner.com/partnercentral2/s/login?startURL=%2Fhome). 2. Click the **Sell** tab. 3. Choose **Opportunity Management**. 4. Click **Create**, or use the **Bulk** option to bulk import all the opportunities. 5. Submit the opportunities. 6. Get at least **10 opportunities** validated and accepted by AWS. To bulk import opportunities: 1. Click **Bulk imports**, scroll to the bottom, and click **Start Import**. 2. Download the Excel template, fill in the relevant information, and import it. 3. Once you have submitted the 10 opportunities, wait until the **Status = Approved**. 4. Once the 10 submitted opportunities are approved, qualify them by updating the **Stage** field to **Qualified**. :::info AWS does not contact your customers or leads. It only validates the business it is partnering with (your company) and confirms that you can submit information about your leads or clients. ::: ### Step 7: Submit a Foundational Technical Review (FTR) **What is an FTR?** A Foundational Technical Review on AWS assesses the architecture, security, and performance of your cloud infrastructure. It ensures your AWS environment follows best practices, meets security standards, and is optimized for performance and cost. Addressing any gaps in these areas helps you build a solid foundation for your AWS deployments and mitigate operational risks. :::info As of June 2026, FTR no longer uses a self-attestation checklist. It's now an automated review based on a compliance document you already have (or can generate), and results return within minutes. ::: **Prerequisites** Checked automatically in Partner Central under the Validation tab on your Solution: - The solution is linked to exactly one AWS Marketplace product - The linked product is a software type (SaaS, AMI, Container, or Machine Learning), Professional Services and other non-software types aren't eligible - The product has an approved, AWS-hosted architecture (upload an architecture diagram in AWS Marketplace Management Portal if you haven't) - The product has Partner Revenue Measurement (PRM) enabled. This can take up to 7 days to reflect after you turn it on, so enable it early **How to complete the FTR:** 1. Sign in to [AWS Partner Central](https://partnercentral.awspartner.com/partnercentral2/s/). 2. Navigate to **Build → Solutions**, then choose your solution. 3. Go to the Validation tab and confirm all prerequisites show Complete. 4. Choose Request validation. 5. For Report type, select either **SOC 2 report** or **WAFR report**: - **SOC 2 Type II report** — must be less than 1 year old, with an unqualified auditor opinion, AWS infrastructure explicitly in scope, and Security and Availability trust criteria included - **AWS Well-Architected Framework Review (WAFR)** — must be less than 1 year old, with zero high-risk issues in the Security, Operational Excellence, and Reliability pillars, and your solution referenced by name 6. Upload your report (PDF, 3 MB max). 7. Choose **Request FTR**. Your submission is reviewed automatically and returns **approval or specific remediation feedback within minutes**. If action is required, resolve the flagged issues and choose Resubmit, you can resubmit as many times as needed. **Once approved, the FTR is valid for 2 years**. The Validation tab shows your expiration date, plan to resubmit before it lapses to keep your badge and program eligibility active. ### Step 8: Check your Software Partner Path Once you have completed the steps above, check your Software Partner Path. Make sure it is in **Validated** status and shows 1 Solution with an approved FTR. ### Step 9: Confirm with the AWS Partner Development team Finally, connect with the AWS Partner Development team to sign off on all completed requirements. --- Source: https://doc.fours.com/cosell/cosell-aws-rep-outreach/ # Automate AWS Sales Rep Outreach Automatically email the AWS Sales Representative attached to any opportunity you share via Fours Co-Sell. --- ## Overview Engaging the AWS Sales Representative early and consistently can be the difference between a stalled opportunity and a co-sell win. With email automation in Fours, every opportunity you share with AWS is accompanied by a timely, personalized message — without adding manual work for your team. The moment a Co-Sell opportunity is submitted, Fours sends a message to the associated AWS Sales Rep, driving better alignment, faster collaboration, and stronger AWS pipeline. The message is populated automatically with details from your Co-Sell opportunity and your Salesforce record. This is ideal for Go-to-Market, Alliances, and Sales Operations teams strengthening their AWS co-sell motion. It builds on your existing Fours + Salesforce setup and only requires a team-managed Gmail alias and a defined email template to get started. You can configure the automated emails to trigger on key Co-Sell opportunity events, such as: - A new opportunity shared via Co-Sell - Status updates (for example, In Progress or Closed Won) - Deal launch or private offer creation - Custom lifecycle stages based on your sales motion ## Referral Trigger Events Two referral events are worth calling out, because they behave differently from each other. ### New AWS team member Fours fires a **New AWS team member** event the first time an AWS-side role is filled on a referral. It covers these roles: | AWS role | | --- | | AWS Sales Rep | | AWS Account Owner | | WWPS PDM | | PDM | | PSM | | ISV SM | The event fires **on the first time a role is populated** — it is the "AWS has staffed this deal" signal, not a change notification for every later edit. **Roles filled in the same sync are batched into one event.** If AWS staffs several roles at once, you get a single notification naming all of them together rather than one per role — for example `AWS PDM, PSM assigned - `. Build your workflow to read the list of roles from the message rather than assuming exactly one. :::warning This event **sends no email**, and it has **no row in Settings → Notification**. There is nothing to switch on there. The only way to consume it is as a **Workflow trigger**, where it is listed as **New Aws Team Member - Referral**. ::: Use it when you want to act the moment AWS assigns someone — for example, to notify your alliances channel, or to kick off the outreach described on this page. ### Referral accepted The referral **Accept** event fires when a referral is accepted, and it now also fires on the **first APN opportunity attach** — so a referral that becomes a real AWS opportunity raises the event even if the acceptance itself happened earlier. Unlike **New AWS team member**, this event is fully configurable: - It **is** email-configurable in **Settings → Notification**. - It routes to **Slack** and **Microsoft Teams** as well as email. ### AWS-side lifecycle change The referral **update** event also fires when AWS changes the deal on their side, even when AWS does not bump the opportunity's last-modified date — which previously meant such a change could pass unnoticed until something else touched the referral. It fires when any of these AWS-owned lifecycle fields moves **to a non-empty value**: | Field | What it signals | | --- | --- | | **Stage** | AWS advanced the opportunity. | | **Next Steps** | The AWS seller recorded what happens next. | | **Target Close Date** | AWS set or revised the expected close date. | | **Closed Lost Reason** | AWS closed the deal as lost, with a reason. | A field being **cleared** does not fire the event — only a move to a real value does. Because an opportunity AWS has not touched yet carries empty values, the **first** time AWS fills any of these counts as a change and raises the event. ## Step 1: Connect a Google Mail Alias to Fours Connect a Google Mail alias account to your Fours organization. This account is the sender for all automated AWS Sales Rep communications. See [How to integrate Google Mail with Fours](/integrations/google-mail). :::tip Use a neutral, team-managed alias such as `partners@yourcompany.com` or `aws-cosell@yourcompany.com` for consistency and visibility. ::: ## Step 2: Create Your Email Template Draft the message you want AWS Sales Reps to receive. Fours populates this template automatically with details from your Co-Sell opportunity, such as: - Opportunity name - Salesforce Opportunity Owner - Relevant Salesforce contact(s) - Any specific call-to-action or ask Once finalized, share the template with your Fours Customer Success Manager (CSM). Here's an example: ```plain Subject: Co-Sell Opportunity for {{Account.Name}} with AWS Hi {{aws_rep_name}}, I wanted to reach out to introduce myself and share details about a new Co-Sell opportunity we've submitted via ACE. Opportunity Name: {{Opportunity.Name}} Customer Name: {{Account.Name}} Estimated Close Date: {{Opportunity.CloseDate}} Opportunity Owner: {{sf_opportunity_owner_name}} ({{sf_opportunity_owner_email}}) We're excited to partner with AWS on this and would love to collaborate further to ensure mutual success. Please let us know how we can support the deal from our side or if you need any additional context. Looking forward to working with you! Best regards, {{Signature}} ``` ## Step 3: Define Additional CC Recipients Decide which additional recipients should be CC'd on the automated emails. Common examples include: - Your Salesforce Opportunity Owner - Your Partner Account Manager (PAM) - Internal stakeholders (for example, your BD or Alliances team) Include this list along with your template when you send them to your CSM. ## Step 4: Request Email Automation Setup Open a support ticket with Fours to trigger setup of the automation workflow. Be sure to include: - Confirmation that your alias email account is connected - The finalized email template - The list of CC recipients and any dynamic fields (for example, Salesforce contacts) Open a ticket from the [Fours support page](https://console.suger.io/support). The Fours team then configures the automation to send emails whenever an opportunity is shared with AWS via Co-Sell. --- Source: https://doc.fours.com/cosell/why-co-sell-with-aws/ # The Benefits of Co-Selling with AWS Co-selling with AWS helps you amplify reach, accelerate deal cycles, and unlock joint revenue opportunities—and Fours automates the engagement with AWS Sales Teams so you can scale faster. --- ## Overview Co-selling with AWS is a go-to-market strategy that aligns your sales motions with AWS. By sharing opportunities through the AWS Co-Sell program, you gain access to dedicated partner resources, benefit from increased customer trust, and maximize the value of your cloud marketplace investments. Fours' Co-Sell initiative streamlines and automates this process—integrating your CRM directly with the AWS ACE system (AWS Partner Central) so you can submit, manage, and track co-sell opportunities without friction. ## Why Co-Sell with AWS? ### 1. Access to AWS Sales Teams By sharing opportunities through the AWS Co-Sell program, you can get your deals in front of AWS Account Managers and Solution Architects. This increases the likelihood of getting AWS support during the sales cycle—particularly for large or strategic opportunities. Fours makes this seamless by integrating your CRM directly with the AWS ACE system (AWS Partner Central), letting you submit, manage, and track co-sell opportunities in one place. ### 2. Accelerated Sales Cycles When AWS reps are involved, they can help validate your solution, introduce you to key stakeholders, and assist with procurement via AWS Marketplace. This can shorten the time from first conversation to signed deal. Fours' workflows ensure that co-sell opportunities are created with the right metadata and mapped to the correct AWS stakeholders from the start. [Configure field mapping using Fours.](/integrations/aws-partner-network-api/) ### 3. Increased Customer Trust Listing and co-selling through AWS gives customers an added layer of credibility. Buyers already engaged with AWS see value in solutions that are AWS-validated and jointly sold. Using Fours to list and co-sell reinforces your cloud-native credibility while simplifying the transaction process for your sales team. ### 4. Access to Incentives and Programs Co-sell-qualified deals may unlock AWS incentives such as Proof of Concept (POC) funding, marketing development funds (MDF), and Private Pricing Agreements (PPAs). Fours helps ensure your co-sell deals are properly tracked in your CRM (Salesforce, HubSpot) and flagged for incentive eligibility through its integrations and automation. ### 5. Simplified Procurement through AWS Marketplace Co-selling also supports transacting through AWS Marketplace, making procurement faster and easier for customers—especially enterprise buyers with AWS spend commitments. With Fours, you can generate private offers and tie them to co-sell opportunities, making the transition from opportunity to transaction effortless. ## How Fours Supports the AWS Co-Sell Process | Co-Sell Stage | Fours' Value | | --- | --- | | **Opportunity Identification** | Easily identify co-sell eligible opportunities from Salesforce by applying your own internal filters to your reports. | | **Opportunity Sharing** | With one click, submit selected CRM opportunities to AWS ACE. [Bulk share CRM opportunities to ACE.](/cosell/cosell-outbound/) | | **Stakeholder Mapping** | Fours automatically identifies the AWS Sales Reps associated with co-sell opportunities and enables event-based workflows to keep them informed. Configure automated email notifications to proactively engage AWS reps as soon as opportunities are shared, improving alignment and response times. | | **Status Tracking** | Centralized tracking and updates within Salesforce or HubSpot. View your entire ACE pipeline within your CRM and monitor opportunity statuses, AWS rep engagement, and key milestones—all in one place, without logging into the ACE portal. | | **Private Offer Creation** | Create AWS private offers directly from your CRM opportunities and automate linking your accepted private offers to co-sell opportunities. | | **Reporting & Attribution** | Track co-sell impact and revenue attribution from one source of truth. Fours provides a Salesforce Dashboard that consolidates co-sell activity, opportunity status, and revenue—giving you full visibility into pipeline performance and AWS partnership impact. | ## Get Started AWS Co-Sell is more than a partnership—it's a growth engine. With Fours' end-to-end co-sell automation, you can focus on what matters: closing more deals, faster, with AWS. For more information or to activate your co-sell automation, contact your Fours CSM or visit the **Co-Sell** tab in the [Fours Console](https://console.suger.io). --- Source: https://doc.fours.com/cosell/cosell-microsoft-fields/ # Co-Sell Fields in Microsoft A reference for the Microsoft solution area and conversation values you map and submit when co-selling through Fours. --- ## Overview Every Microsoft co-sell referral carries two related values: a **solution area** — the broad part of the Microsoft portfolio the deal belongs to — and a **conversation**, the specific motion inside that area. Microsoft validates the pair, so a conversation that does not belong to the solution area you chose is rejected. This page lists the current catalog and explains how Fours handles values from earlier Microsoft fiscal years, which you will still see on older referrals. To control how these values are pre-filled from your CRM, see [Field Mapping](/cosell/cosell-configuration/) in the Co-Sell configuration guide. For the AWS equivalent of this page, see [Co-Sell Fields in ACE](/cosell/cosell-ace-fields/). ## "Solution Play" is now "Conversation" Microsoft renamed *solution play* to **conversation**. Fours follows the new name, but the transition leaves a few things worth knowing: | Where you look | What you see | | --- | --- | | **The UI label** | "Solution Play/Conversation" — both names, so the field is findable either way. | | **The field-mapping key** | Still `SolutionPlay`. Existing mappings keep working; you do not need to rewrite them. | | **A newly created referral** | Always written as **Conversation**. Fours normalizes on create regardless of which name you sent. | | **An updated referral** | Whichever name **you** send is preserved. An older client can keep updating `SolutionPlay` without being forced onto the new name. | ## Solution areas and conversations There are **five** solution areas, carrying **11** area-and-conversation combinations between them: | Solution area | Conversation | | --- | --- | | **AI Business Solutions** | AI-ready productivity and security for every employee | | **AI Business Solutions** | Agentify your business processes | | **AI Business Solutions** | AI in the flow of human ambition | | **Cloud and AI Platforms** | Modernize with confidence | | **Cloud and AI Platforms** | Build a unified governed data and AI estate | | **Cloud and AI Platforms** | Amplify your intelligence | | **Cloud and AI Platforms** | Ubiquitous Innovation | | **Microsoft Services** | Accelerate AI Transformation with Microsoft Services | | **Security** | AI-ready productivity and security for every employee | | **Security** | Establish a trusted and secure platform for AI | | **Windows and Devices** | AI Transformation with Surface and Copilot | Note that **AI-ready productivity and security for every employee** is valid under two solution areas — **AI Business Solutions** and **Security**. Pick whichever area matches how the deal is being sold; both pairs are accepted. :::warning **`Microsoft Unified` is retired.** It is no longer a selectable solution area. Referrals created against it in an earlier catalog still exist — see [Values from earlier catalogs](#values-from-earlier-catalogs) — but you cannot choose it for anything new. ::: ## Values from earlier catalogs Microsoft revises this catalog by fiscal year, and Fours handles each generation differently: | Situation | What Fours does | | --- | --- | | You **create** a referral with a current value | Sent as-is. | | You **create** a referral with an **FY26** value | Automatically mapped forward to its current equivalent. You do not have to re-pick it. | | You **update** a referral holding an **FY25** value | **Rejected.** FY25 values were never accepted on update — set a current value on the referral instead. | | A stored value is outside the current catalog | Displayed with a **`(legacy)`** marker, so you can tell at a glance that the value predates the current catalog. | The `(legacy)` marker is informational. It does not stop you reading the referral or working the deal — it tells you that if you edit the referral, you should expect to pick a current value. :::tip If a Microsoft referral fails with a solution-area or conversation error, check the pair rather than each value alone. A valid area and a valid conversation still fail when the conversation does not belong to that area — the table above is the authoritative list of valid combinations. ::: --- Source: https://doc.fours.com/cosell/cosell-leads/ # AWS Partner Central Leads Accept the leads AWS Partner Central sends you, create leads from your Salesforce Accounts, and qualify, edit, and convert them. --- ## Overview A **lead** is an earlier-stage prospect than an ACE opportunity. AWS invites you to a lead it has sourced; you accept or reject the invitation, work the prospect through a qualification funnel, and — once it is genuinely qualified — convert it into a co-sell opportunity that follows the normal [referral lifecycle](/cosell/cosell-status/). Leads are **AWS-only**, and they reach Fours in one of two ways: | Origin | How the lead starts | **Lead source** on the lead page | | --- | --- | --- | | **AWS invitation** | AWS invites you to a lead it has sourced, and you accept or reject it. | `AWS` | | **Lead enrichment** | Fours submits one of your Salesforce Accounts to AWS, which creates the lead and returns what it knows about the company. See [Create Leads from Salesforce Accounts](#create-leads-from-salesforce-accounts). | `Salesforce Account (enrichment)` | Both kinds share the lead list and the same qualify, edit, and convert steps. Only an AWS invitation has to be accepted first: a lead created by enrichment starts out accepted. ## Where to Find Leads Leads live in the co-sell referrals list, under AWS: 1. Open the co-sell referrals list in the [Fours Console](https://console.suger.io). 2. Pick **Lead**, one of three AWS views alongside **ACE opportunity** and **Engagement invitation**. Where you find it depends on how many cloud partners your organization has: - **More than one cloud partner:** hover over the **AWS** chip in the partner filter, then pick **Lead**. - **AWS is your only cloud partner:** there is no partner chip group. Pick **Lead** in the three-option control next to the search box. The list switches to the lead table. Click any row to open the lead detail page. Clicking the selected option again clears it. The same controls stay on the lead table's toolbar, so you can switch back to ACE opportunities or engagement invitations at any time. :::note The **Lead** option appears only on the co-sell referrals list. It is not offered in the Partner Management (PRM) view of the same table, because leads are an AWS relationship rather than a partner-to-partner one. ::: ### Lead list columns | Column | What it shows | | --- | --- | | **Name** | The lead's name, as AWS supplies it. | | **Cloud Partner** | Always `AWS`. | | **Company** | The prospect's company name. | | **Invitation Status** | Where the AWS invitation stands: `PENDING`, `ACCEPTED`, `REJECTED`, or `EXPIRED`. | | **Qualification** | How far you have worked the prospect — see [Qualify the lead](#qualify-the-lead). | | **Readiness Score** | The AWS lead readiness score from the lead's AI insights. | | **Status** | The single unified status that folds the two axes above together — see [Lead statuses](#lead-statuses). | | **Expiration** | When the invitation lapses if you do not act on it. | | **Creation Time** | When the lead was created. | Use the **Columns** control to show or hide any of them. ## The Lead Lifecycle ```d2 direction: down pending: "PENDING\ninvitation from AWS" decide: "Accept or reject?" { shape: diamond } rejected: "REJECTED\nreason required" expired: "EXPIRED\ninvitation lapsed" enriched: "Created from a Salesforce Account\nby lead enrichment" accepted: "ACCEPTED" qualify: "Set qualification\nUnqualified · Open · Research\nQualified · Disqualified" gate: "Qualification = Qualified?" { shape: diamond } blocked: "Convert to Opportunity\nstays disabled" converted: "CONVERTED\nco-sell opportunity created" pending -> decide decide -> accepted: "Accept\nqualification starts at Unqualified" decide -> rejected: "Reject" pending -> expired: "no action before expiration" enriched -> accepted: "no invitation\nqualification starts at Open" accepted -> qualify qualify -> gate gate -> blocked: "no" blocked -> qualify: "keep working the prospect" gate -> converted: "yes — Convert to Opportunity" ``` ## Accept or Reject an Invitation While the invitation status is `PENDING`, the lead detail page offers two actions: - **Accept** — takes the lead. The invitation status becomes `ACCEPTED` and AWS sets the qualification to `Unqualified` to start the funnel. - **Reject** — declines the lead. In the Fours Console a **reason is required**: the Reject button in the dialog stays disabled until you enter one. (Working the same lead from the Salesforce app, the reason is optional — see [Work AWS Co-Sell Leads](/salesforce-app/salesforce-app-leads/).) If you act on neither, the invitation lapses at its **Expiration** date and the lead becomes `EXPIRED`. A lead created by [lead enrichment](#create-leads-from-salesforce-accounts) has no invitation, so it never offers **Accept** or **Reject**. It opens already `ACCEPTED`. ## Qualify the Lead Once a lead is `ACCEPTED`, the detail page header shows a **Qualification** picker. Setting it is what moves the lead down the funnel: | Qualification | Meaning | | --- | --- | | **Unqualified** | The AWS default the moment you accept. Nothing has been worked yet. | | **Open** | You have picked the prospect up. | | **Research** | You are actively investigating fit. | | **Qualified** | The prospect is a real opportunity. **This is the only value that unlocks conversion.** | | **Disqualified** | Not a fit — the lead stops here. | Changing the picker writes the new value to AWS. Fours stores it locally only after AWS accepts the write, so a rejected update can never leave Fours showing a qualification AWS does not have. :::note AWS treats the qualification as a free-text field capped at **255 characters**, not a strict enum, so a lead can arrive carrying a value outside the five above. Fours displays whatever AWS sent, and the picker lists that value alongside the five. An update to an accepted lead has to change something: the qualification, the company details on the [Edit lead](#edit-a-lead) page, or both. An update with neither is rejected with `an accepted lead update must carry a qualificationStatus, a customer patch, or both`, and a qualification over the cap with `qualificationStatus exceeds the 255-character limit`. ::: You can also use **Link With CRM** to attach the lead to an existing CRM record before converting it. ## Edit a Lead Once a lead is `ACCEPTED`, click **Edit** in the lead page header to open the **Edit lead** page and correct what AWS holds about the prospect. It has two sections: | Section | What you can change | | --- | --- | | **Company details** | **Customer company name** (AWS allows up to 120 characters), **Customer website**, **Industry** (from AWS's industry list), **Market segment** (`Enterprise`, `Large`, `Medium`, `Small`, or `Micro`), **AWS maturity** (free text), and **Country**. | | **Lead qualification** | The **Qualification state**: `Unqualified`, `Disqualified`, `Qualified`, or **Other** — your own description of 1 to 255 characters, sent to AWS as the qualification. A lead whose qualification is outside the first three, such as `Open` or `Research`, opens on **Other** with its value filled in. | Click **Save lead** to send the change to AWS. Before you save: - **What you empty is cleared at AWS.** The page sends every field, so emptying **Customer website** or **AWS maturity** removes that value from the lead. The company name can't be emptied: AWS requires one. - **A stale page is refused.** The page remembers the version of the lead it opened. If the lead changed at AWS since then, the save is rejected with `this lead changed at AWS since the form was opened, so the edit was not applied; reload the lead and re-apply the change`. Reopen the lead, make your change again, and save. - **Sync first if the page asks.** A lead that has no version from AWS yet can't be edited safely. Use **Sync** on the lead page, then edit again. - **The contact isn't edited here.** The person on a lead belongs to its interactions, which record what happened rather than a record to revise. Only an accepted lead can be edited. For one that is still `PENDING`, accept the invitation first. ## Convert to an Opportunity **Convert to Opportunity** turns the lead into a co-sell opportunity that then follows the normal referral lifecycle. The button is enabled only when every one of these holds: - The invitation status is `ACCEPTED` — otherwise: `only an accepted lead can be converted`. - The lead has not already been converted — otherwise: `lead is already converted`. - The qualification is exactly **Qualified** — otherwise: `lead must be Qualified to convert`. After a successful conversion the lead's status becomes `CONVERTED` and the new referral appears in the co-sell list. ## Lead Statuses The **Status** column collapses the invitation status, the qualification, and whether the lead has been converted into one value: | Status | When you see it | | --- | --- | | `PENDING_ACCEPTANCE` | The invitation is still `PENDING`. | | `REJECTED` | You rejected the invitation. | | `EXPIRED` | The invitation lapsed before you acted. | | `OPEN` | Accepted, and the qualification is `Unqualified`, `Open`, or a value Fours does not recognise. | | `RESEARCH` | Accepted, qualification `Research`. | | `QUALIFIED` | Accepted, qualification `Qualified` — ready to convert. | | `DISQUALIFIED` | Accepted, qualification `Disqualified`. | | `CONVERTED` | Converted into a co-sell opportunity. | | `DELETED` | The lead was deleted. | ## The Lead Detail Page The lead page mirrors AWS Partner Central's own lead page, block for block. Its header shows the lead's name, invitation status, and status, with the actions that apply: | When | Actions | | --- | --- | | Invitation `PENDING` | **Accept**, **Reject** | | `ACCEPTED` | **Qualification** picker, **Link With CRM**, **Edit**, **Convert to Opportunity** | | Any state | **Detail** (the raw lead record) and **Sync** (re-pull the lead from AWS) | Below the header: | Block | What it shows | | --- | --- | | **Source record** | Only on a lead created by enrichment: the Salesforce object and record ID it was built from. | | **Lead details** | Lead ID, qualification state, **Lead source** (`AWS` or `Salesforce Account (enrichment)`), creation date, and target close date. | | **Company details** | Company, contact name, country, website, email, AWS maturity, industry, phone, and market segment. | | **Lead enrichment** | What AWS returned about the prospect. See [Lead enrichment and AWS insights](#lead-enrichment-and-aws-insights). | | **Interactions** | Each interaction AWS recorded, with a search box: name, date, lead source, customer action, and use case. Click an interaction's name for its business problem and the contact behind it. | | **Linked CRM Record** | The Salesforce opportunity or HubSpot deal attached with **Link With CRM** and, once the lead is converted, a link to the converted referral. | ### Lead enrichment and AWS insights The **Lead enrichment** block leads with AWS's scores: | Field | What it tells you | | --- | --- | | **Readiness** | The AWS lead readiness score. | | **AWS Marketplace solution score** | The solution category and sub-category AWS matched, shown with how strong the match is — for example, `High propensity`. | | **Expiration** | When the invitation lapses. | When AWS has returned an enrichment result for the lead, an **AWS insights** section opens under them with AWS's view of the customer: account name, geography, marketplace engagement score, industry, region, program eligibility, sub-industry, sub-region, segment, company size, country, and a public profile summary. A lead AWS has not enriched shows no AWS insights section, and a field AWS did not populate is blank. ## How Leads Reach Fours Fours pulls leads from AWS Partner Central on a schedule, **every three hours** — at 01:30, 04:30, 07:30, 10:30, 13:30, 16:30, 19:30, and 22:30 UTC. The lead sweep is deliberately offset by 30 minutes from the referral inbound sync so the two do not start at the same moment. What you change on a lead — accept, reject, qualification, an edit — is pushed to AWS as you do it rather than on a schedule. The one scheduled run in the other direction is [lead enrichment](#create-leads-from-salesforce-accounts), which creates new leads from your Salesforce Accounts once a day at 03:15 UTC while its automation is on. To pull immediately instead of waiting, use the **Inbound Sync** button above the lead table. That manual run is a **full sync** — it re-reads every lead rather than only what changed recently, so it is the way to recover a lead the scheduled run missed. Leads sync on their own track, independent of the [referral inbound sync](/cosell/cosell-syncing/): running one does not run the other. ## Create Leads from Salesforce Accounts **Lead enrichment** turns your Salesforce Accounts into AWS leads. Fours submits an Account to AWS Partner Central, AWS creates a lead for it and returns what it knows about the company, and the lead joins your lead list next to the ones AWS sends. It is AWS-only and reads from Salesforce only. ```d2 shape: sequence_diagram salesforce: "Your Salesforce" suger: Fours aws: "AWS Partner Central" suger -> salesforce: "Daily at 03:15 UTC: read the Accounts your sync filter selects" salesforce -> suger: "Account fields and each Account's contacts" { style.stroke-dash: 4 } suger -> suger: "Skip Accounts already submitted, pick the contact, check the required inputs" held: "if an Account can't be submitted" { suger -> suger: "Count it as not submitted, with the reason. Nothing is sent to AWS" } sent: "for every other Account" { suger -> aws: "Create the lead and ask AWS to enrich it" aws -> suger: "Enrichment result, or no data" { style.stroke-dash: 4 } suger -> suger: "Add the lead to your lead list: ACCEPTED, qualification Open" } ``` Before you start, connect [Salesforce](/integrations/salesforce/) and your [AWS Partner Central (ACE) integration](/integrations/aws-partner-network-api/). Fours checks the mapping against your live Salesforce schema when you save it, so a mapping can't be saved while Salesforce is unreachable. AWS also decides whether your Partner Central account may create leads this way. If it doesn't, each Account is refused with `PARTNER_LEAD_CREATION_NOT_ENABLED` until the capability is enabled on the AWS side. ### Open the mapping 1. In the [Fours Console](https://console.suger.io), open the **Co-Sell** page, select its **Settings** tab, and then the **Lead Enrichment** sub-tab, which holds **Lead Enrichment Mapping Configs**. The sub-tab appears only when your organization has a verified Salesforce integration; without one, there is nothing to set up here. 2. On the **Salesforce Account → AWS Lead** card, click **Configure** — or **Edit**, once a mapping is saved. 3. Set up the **Field Mapping** and **Sync Filter** tabs described below, then click **Save**. The card's badge shows where things stand: **Not configured**, **Automation off** (saved, but nothing runs on a schedule), or **Automation on**. **History** lists every change to the mapping. ### Map the Account fields On the **Field Mapping** tab, each AWS input reads a field on the Salesforce Account. For each row, choose **CRM field** and pick an Account field, or choose **Fixed value** and type what to send for every Account. A blank row reads the input's standard Account field: | AWS input | Required | Standard Account field | | --- | --- | --- | | Company Name | Yes | `Name` | | Website URL | Yes — CRM field only | `Website` | | Industry | Yes | `Industry` | | Country Code | Yes | `BillingCountry` | | State or Region | When the country is US | `BillingState` | | City | No | `BillingCity` | | Postal Code | No | `BillingPostalCode` | | Phone | No — the company switchboard, not a person's line | `Phone` | | Use Case | No | none | | Business Problem | No | none | - **A new mapping starts filled in.** Each row starts on its standard field, or, for company name, website, industry, and country, on the custom field your **Account Mapping Configs** already name. - **Website URL can't be a fixed value.** Fours matches each contact's email domain against it, so it has to be read from each Account. - **Country needs a two-letter code.** AWS accepts ISO 3166-1 alpha-2 codes. Fours converts a name such as `United States`, or a code such as `USA`, to `US`; an Account whose country it can't convert is not submitted. - **Row ID is fixed.** AWS keys each lead on the Salesforce record ID, which Fours always sends. A row takes a field or a fixed value, not both. When you save, Fours lists every problem at once under **Cannot save**, and anything it could not check under **Saved, with things we could not check**. ### Where the person on the lead comes from AWS requires a named contact on every lead: first name, last name, email, and business title, with phone optional. A Salesforce Account holds no person, so these aren't mapped. Fours uses the **most recently active contact on the Account whose email domain matches the Account website**, and the most recently created one when several tie. The domain match is exact: a contact at `partner.acme.com` is not treated as an employee of `acme.com`. An Account with no website, no contacts with an email address, or no contact at a matching domain is skipped and counted. It is never submitted with a guessed person. To name the person yourself, set **Primary contact field** to a Lookup-to-Contact field on the Account. Salesforce has no standard one, so pick whichever field your org uses. Where that field has a value, its contact is used as-is and the domain rule doesn't apply. It must still be a contact on the same Account, with an email address; otherwise it is ignored, and the domain rule picks the person instead. The Account still needs a website: without one it isn't submitted, even with a primary contact. ### Translate industry values AWS accepts a fixed list of industries. The **Industry Value Mapping** card maps each value of your Salesforce industry field to one of AWS's, and it starts filled in for Salesforce's standard Industry picklist. Add a row for any other active value your field offers: a value in use with no translation blocks the save, so no Account is sent with an industry AWS would reject. ### Choose which Accounts to submit On the **Sync Filter** tab, write the Salesforce condition that selects which Accounts to submit — the condition only, for example `Type = 'Prospect' AND CreatedDate = LAST_N_DAYS:90`. Fours builds the query itself and reads the fields your mapping names. Relationship fields such as `Account.Industry` aren't supported, and the condition can't carry its own `SELECT`, `FROM`, `ORDER BY`, or `LIMIT`. **Which date literals can I use?**, above the box, lists the Salesforce date literals you can use. Click **Validate** to run the filter read-only against Salesforce. It reports how many Accounts match, with a sample of their IDs, and submits nothing. The readiness panel at the top of the page tells you whether the scheduled run would work, without a save: **Ready to run**, or how many required inputs have nothing behind them and how many industry values have no translation. After **Validate**, it also counts how many of the most recently created matching Accounts can't be submitted, and why: | Reason | What to fix in Salesforce | | --- | --- | | No website on the account | Add the Account's website. Fours needs it to match a contact. | | No contacts with an email address | Add a contact with an email address to the Account. | | No contact whose email domain matches the website | Add a contact at the Account's own domain, or set a **Primary contact field**. | ### Turn on automation The **Automation** switch, **Automatically create AWS leads from this filter**, is off by default. Saving or validating a filter never creates anything; this switch is the only thing that does. While it is on, Fours runs once a day at **03:15 UTC** and submits the Accounts your filter selects: - **The scheduled run submits each Account once.** An Account whose enrichment already finished is skipped, whatever the outcome, so turning automation off and on again never resubmits it. - **Up to 500 Accounts per organization per run.** A larger backlog carries over to the next day's run. - **An empty filter selects nothing.** It is never read as "every Account". Nothing re-enriches an Account automatically. To enrich a single Account on demand, even with automation off, or to re-enrich one once 30 days have passed since its last enrichment, use the Fours widget in Salesforce. See [Work AWS Co-Sell Leads](/salesforce-app/salesforce-app-leads/). An on-demand request for an Account that has no lead yet is checked before anything is sent to AWS, against the same input rules as the scheduled run: the company details, the country code, the state of a US Account, the industry translation, and the contact's name, email, and business title — the first six reasons under [What each Account becomes](#what-each-account-becomes). An Account that fails one is refused at once, with the reason shown in the widget as `this account cannot be submitted: …`, instead of starting an enrichment that never produces a lead. Re-enriching an Account that already has a lead skips these six checks, because it works the existing lead rather than creating one; the Account still needs a contact Fours can pick (see [Where the person on the lead comes from](#where-the-person-on-the-lead-comes-from)). ### What each Account becomes A submitted Account becomes a lead that starts `ACCEPTED` with qualification `Open`, so you can qualify, edit, and convert it straight away. Its **Lead source** reads `Salesforce Account (enrichment)`, and its **Source record** block names the Account it came from. To see what happened to each Account, open **Metrics > Logs** and set **Workflow Type** to **Lead Enrichment**. Each Account the run submits has its own row, with one of these outcomes: | Outcome | What it means | | --- | --- | | **Enriched** | AWS returned intelligence for the company. It appears in the lead's **Lead enrichment** block. | | **No data** | AWS completed the enrichment but had nothing on this company. | | **Failed** | AWS's enrichment task failed or did not finish. | | **Rejected** | The Account was refused before a lead was created, for the reason shown. | A rejection names its reason: | Reason | What it means | What to do | | --- | --- | --- | | **Incomplete company details** | The Account has no company name, website, or country. | Fill them in, or map other fields. | | `UNTRANSLATED_COUNTRY_VALUE` | The country isn't a two-letter code, and Fours can't convert it to one. | Map a country-code field, or set a fixed value. | | **State required for US** | A US Account has no state or region. | Fill in the Account's state. | | **Industry has no AWS equivalent** | The Account's industry has no translation. | Add it to **Industry Value Mapping**. | | **Incomplete contact details** | The contact Fours picked has no first name, last name, or email. | Complete the contact in Salesforce. | | **Required field not mapped** | The contact Fours picked has no business title, which AWS requires. | Add the contact's title in Salesforce. | | `PARTNER_LEAD_CREATION_NOT_ENABLED` | AWS doesn't allow your Partner Central account to create leads. | Ask AWS to enable it. | | `ENGAGEMENT_ALREADY_EXISTS` | AWS already holds a lead for this Account, but Fours has none. | Leave the Account out of the filter, or contact [support@suger.io](mailto:support@suger.io). | | **Already enriched** | The Account already has a lead from enrichment. | Nothing to fix. | ### Older mappings and deleting a mapping - **A mapping saved before the Account source.** Lead enrichment used to read Salesforce Leads and Contacts. If your organization saved a mapping then, the section shows **Your saved mapping predates the Account source**: the old mapping is kept but no longer used, and scheduled enrichment doesn't run until you save an Account mapping. - **Deleting the mapping** stops scheduled enrichment, and enrichment from Salesforce is refused until a mapping exists again. ## Related - [Work AWS Co-Sell Leads](/salesforce-app/salesforce-app-leads/) — the same lifecycle worked from the **Leads V2 (Suger)** tab in Salesforce, without leaving your CRM. - [Inbound Referral](/cosell/cosell-inbound/) — accepting the ACE opportunities AWS sends, which is where a converted lead ends up. - [Status & Stage](/cosell/cosell-status/) — the unified statuses a converted lead's referral moves through. - [Co-Sell Fields in ACE](/cosell/cosell-ace-fields/) — the AWS fields on the resulting opportunity. - [Configuration](/cosell/cosell-configuration/#three-different-enrichment-features) — how lead enrichment differs from Auto-Enrich Referrals and CRM intelligence-signal enrichment. --- Source: https://doc.fours.com/cosell/ # Co-sell Co-selling is how you bring a cloud provider into a deal your team is already working: you share the opportunity, their sellers engage, and the deal often transacts through the marketplace afterwards. Fours connects your CRM — Salesforce, HubSpot, or Dynamics 365 — to AWS Partner Central (the APN Customer Engagement, or ACE, program), Azure Co-Sell, and Google Cloud Partner Network, so your reps share opportunities, accept the referrals the cloud sends back, and watch all of it in one list instead of three partner portals. Fours also carries **partner-to-partner** referrals between two companies that both use Fours, which appear alongside the clouds as a fourth partner. This section covers the full referral lifecycle — configuring the field mappings, sharing outbound, accepting inbound, and keeping every record aligned afterwards — plus the AWS-specific programs that hang off it: funding, engagement scores and AI insights, and automated outreach to the AWS sales rep on the deal. Once a referral exists, Fours keeps your CRM, Fours, and the cloud partner in step for the life of the deal, with no manual re-entry. ## Start here 1. **[Configuration](/cosell/cosell-configuration/)** — the translation layer between your CRM and each partner portal: field mappings, templates, picklist conversions, and which fields stay in sync. 2. **[Outbound Referral](/cosell/cosell-outbound/)** — pick an opportunity out of the Outbox and share it with a cloud partner, one at a time or in bulk. 3. **[Inbound Referral](/cosell/cosell-inbound/)** — accept or decline referrals the cloud sends you, and let Fours create the matching account, opportunity, and contacts in your CRM. 4. **[Status & Stage](/cosell/cosell-status/)** — read one unified Fours status instead of learning AWS stages, Azure sub-statuses, and GCP states separately. ## Qualify and configure - **[The Benefits of Co-Selling with AWS](/cosell/why-co-sell-with-aws/)** — why teams co-sell in the first place: wider reach, shorter deal cycles, and joint revenue. - **[ACE Eligibility](/cosell/cosell-ace-eligibility/)** — the steps you complete in AWS Partner Central to become eligible for AWS leads and opportunities, from joining APN through the Foundational Technical Review. ## Share deals and work what comes back - **[AWS Partner Central Leads](/cosell/cosell-leads/)** — earlier-stage prospects, either sent by AWS or created from your Salesforce Accounts by lead enrichment: accept or enrich, qualify and edit, then convert a qualified lead into a co-sell opportunity. - **[Referral Syncing](/cosell/cosell-syncing/)** — what keeps a referral current once it exists: which direction each change flows, how often scheduled syncs run, and how to force one. ## Track the deal and bring AWS in - **[Co-Sell Insights](/cosell/co-sell-insights/)** — the Insights tab in the Fours widget: warning cards, opportunity and funding insights, and recommended next actions. - **[AWS Funding](/cosell/cosell-funding/)** — apply to any of the seven AWS funding programs, respond to reason codes when a request is sent back, file cash claims, and watch your funding wallets. - **[Automate AWS Sales Rep Outreach](/cosell/cosell-aws-rep-outreach/)** — email the AWS rep attached to a shared opportunity automatically, from a team alias, on the events you choose. ## Look up fields and automate co-sell - **[Co-Sell Fields in ACE](/cosell/cosell-ace-fields/)** — what AWS expects in each ACE field, which ones are mandatory, and how to map them well from your CRM. - **[Co-Sell Fields in Microsoft](/cosell/cosell-microsoft-fields/)** — the Microsoft solution areas and conversations, and how the Solution Play field maps forward across fiscal-year catalogs. - **[Create a Referral via API](/cosell/cosell-referral-api/)** — the request payload for `POST /org/{orgId}/cosell/referral`; one endpoint serves all three clouds. - **[Co-Sell with AI (MCP)](/cosell/cosell-mcp/)** — run the referral lifecycle from Claude, Cursor, VS Code, or another MCP client in plain language. ## Scope and limits :::info Co-sell in Fours covers **four partners** — AWS, Microsoft Azure, Google Cloud, and **Fours** (partner-to-partner) — across **three CRMs**: Salesforce, HubSpot, and Dynamics 365. Any partner can be paired with any CRM, so the co-sell surface is a 4 × 3 matrix. Each of AWS, Azure, and GCP appears as a cloud partner once you have connected the matching integration. **Fours** is different: it is offered as a cloud partner only when **Partner Management (PRM) is enabled** for your organization. If you do not see `SUGER` in the Cloud Partner picker, that is why — see [Partner Management](/prm/) or contact [support@suger.io](mailto:support@suger.io). You do not need a cloud partner to use co-sell. An organization whose only co-sell relationship is a Fours partner-to-partner connection still gets the full co-sell area — the referral list, the inbox, and the outbox all work with `SUGER` as the partner. Inbound sync covers AWS, Azure, and GCP. Fours partner-to-partner referrals are excluded from it because there is no external system to pull from; see [Configuration](/cosell/cosell-configuration/) for the inbound settings each partner offers. Several capabilities are AWS-only: funding, Co-Sell Insights, and sales-rep outreach. Funding and Insights both require your ACE portal to be migrated to AWS Partner Central 3.0, and the Co-sell AI features behind Insights are enabled by Fours — contact [support@suger.io](mailto:support@suger.io). ACE eligibility itself is granted by AWS in Partner Central — Fours does not grant it. Destructive and org-wide actions — deleting a referral, bulk-syncing a whole org, auto-share, and system configuration — are deliberately not exposed as MCP tools, and neither are funding applications. Do those in the [Fours Console](https://console.suger.io). ::: --- Source: https://doc.fours.com/integrations/quickbooks/ # QuickBooks Connect QuickBooks Online to Fours so your marketplace billing flows straight into your accounting ledger. --- ## Overview QuickBooks is a cloud accounting platform for invoicing, payments, and financial reporting. Connecting QuickBooks to Fours opens a secure OAuth channel between your marketplace billing and your QuickBooks ledger, so invoices and related billing data can sync into the QuickBooks Company Account you choose. ### Org-Level vs User-Level > **Org-Level Only**: QuickBooks connects at the organization level using a QuickBooks Developer App (Client ID and Client Secret) plus an OAuth authorization to a single Company Account. The connection is shared across your organization. ## Create Integration (Org-Level) Setting up QuickBooks has three parts: configure a QuickBooks Developer App, complete the OAuth handshake in Fours, then verify the connection. ### Prerequisites - A QuickBooks Online account with the Company Account you want to sync - Access to the [QuickBooks Developer Portal](https://developer.intuit.com) to create an app and retrieve credentials ### Step 1: Configure your QuickBooks Developer App Before Fours can talk to your ledger, set up a secure communication channel in the QuickBooks Developer Portal. 1. **Set the Redirect URI**. In your app settings, add the following Redirect URI exactly: ``` https://api.suger.cloud/public/integration/quickbooks/oauthCallback ``` 2. **Retrieve credentials**. Go to the **Keys & credentials** section of your app. 3. **Copy your Client ID and Client Secret**. Keep these secure and never share them publicly. ### Step 2: Establish the handshake in Fours Once you have your credentials, initiate the OAuth handshake from the Fours side. 1. In the [Fours Console](https://console.suger.io/settings?tab=integrations), go to **Settings > Integrations**. 2. Find the QuickBooks card and click **Connect**. 3. Paste your **Client ID** and **Client Secret** into the respective fields. 4. A QuickBooks login page opens. Sign in and select the specific **Company Account** you want to connect to Fours. 5. Review the permissions and click **Connect**. You are returned to the Fours Console automatically. ### Step 3: Verify and test A status of **Connected** means the connection is open; **Verified** confirms data is flowing. 1. Find QuickBooks in your active integrations list and click **Verify**. 2. Fours reads a small sample of recent data to confirm the connection is active. 3. When the status changes to **Verified**, your marketplace-to-ledger pipeline is live. ## Edit Integration Editing credentials is not supported. To change keys, delete the integration and reconnect with the new Client ID and Client Secret. ## Delete Integration To disconnect from the Fours side, click the **Trash** icon on the QuickBooks card to purge the stored credentials. To disconnect from the QuickBooks side, go to **Account Settings > Connected Apps** in QuickBooks and uninstall the Fours app. :::info Disconnecting stops all future syncing but does not delete any data or invoices already pushed into your QuickBooks ledger. ::: --- Source: https://doc.fours.com/integrations/anthropic/ # Anthropic Connect your Anthropic API key for unlimited features at cost. --- ## Overview By integrating your Anthropic account with Fours, you can utilize your own Anthropic API key. This allows you to access certain AI-powered features within Fours, with billing for API usage handled directly by Anthropic. ### Org-Level vs User-Level There are two types of Anthropic integrations: | Type | Description | Billing | |------|-------------|---------| | **Org-Level** | Uses Anthropic API key for org-wide access to Claude models | Billed to the organization | | **User-Level** | Either a personal **API key**, or a **Claude Code** connection tied to your own Anthropic account | Billed to the individual user | At the user level there are **two connection methods** — connect with an API key, or connect Claude Code. Both are personal to you and billed to you; pick whichever matches how you already pay Anthropic. See [Create User Integration](#create-user-integration) below. ## Create Integration (Org-Level) 1. Navigate to the [Fours Console Integration](https://console.suger.io/settings?tab=integrations) page. 2. Find the **Anthropic** integration and click the `Connect` button. 3. In the dialog that appears, provide the following information: - **API Key**: Your Anthropic API key for accessing Claude models. > Anthropic integration dialog with API key field ## Create User Integration Use a user-level integration when you want Claude to run against **your own** Anthropic account with individual billing. Two connection methods are available. ### Option 1 — Anthropic API key Use this when you have an Anthropic API key of your own. 1. Click `Connect Now` button in the User Integrations section 2. Enter your personal Anthropic API key 3. Return to Fours to confirm connection ### Option 2 — Claude Code Use this when you want to connect your Anthropic account itself rather than manage an API key. This method uses a **manual code-paste (PKCE) authorization** — Fours gives you an authorization link, you approve it with Anthropic, and Anthropic hands you back a code that you paste into Fours to finish the connection. No API key is created or stored. 1. Find the **Claude Code** card in the User Integrations section and click `Connect Now`. 2. The **Connect Claude Code** dialog opens. Click **Open authorization page** — it takes you to Anthropic. 3. Sign in to your Anthropic account if prompted, and approve the request. 4. Anthropic displays an authorization **code**. Copy it. 5. Paste it into **PKCE authorization code** and click **Complete connection**. The field also accepts the whole callback URL, a query string, or a `code#state` value, so you do not have to pick the code out by hand. The integration then shows as connected. ![The Connect Claude Code dialog — the instruction to open the authorization page and paste the code back, an "Open authorization page" button, and the PKCE authorization code box above the Complete connection button](images/claude-code-connect-dialog.png) :::info The link-then-paste step is intentional: it keeps the authorization on Anthropic's own page and means Fours never sees your Anthropic password. Complete the paste in the same sitting — if you leave the dialog before pasting the code, start the connect flow again to get a fresh link. ::: This is the Anthropic counterpart to the OpenAI **Codex** user integration, which uses a device-code flow instead — see [OpenAI](/integrations/openai/#create-user-integration-codex). :::warning Deleting the integration will remove access to Claude immediately. Your API key is stored securely but deletion cannot be undone. ::: ## Edit Integration Editing the Anthropic integration is not supported. To change the API key, you must delete the current integration and create a new one. ## Delete Integration You can delete the Anthropic integration at any time. Please be aware that this action is irreversible and will permanently remove the integration credentials. --- Source: https://doc.fours.com/integrations/apollo/ # Apollo ## Overview Apollo is a sales intelligence platform that provides comprehensive data about leads, contacts, and companies. It helps users find verified contact information, enrich CRM data, and streamline outbound prospecting workflows. ### Org-Level vs User-Level > **Org-Level**: Uses API key for organization-wide access. Best for company-wide data sync. > > **User-Level**: Not typically supported for CRM integrations - data is organization-owned. ## Create Integration (Org-Level) ### Prerequisites - Apollo account with API access - Apollo API key with appropriate permissions ### Authenticate by API Key 1. Navigate to Settings > Integrations 2. Click "Connect Apollo" 3. Enter your Apollo API key 4. Verify the connection ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration from Fours. :::warning This does not delete your data in Apollo. ::: --- Source: https://doc.fours.com/integrations/asana/ # Asana ## Overview Asana is a work management platform for organizing tasks, projects, and workflows. Integrate with Asana to create and manage tasks, projects, and workspaces from Fours and to automate task workflows. ### Org-Level vs User-Level > **Org-Level**: Uses an Asana Service Account token for organization-wide access. Best for shared, company-wide automation. > > **User-Level**: Uses OAuth to connect an individual's Asana account for personal task and project management. ## Create Integration (Org-Level) ### Prerequisites - An Asana Enterprise-tier plan (Service Accounts are an Enterprise feature) - Super admin access to create a Service Account (Admin console → **Apps** → **Service Accounts** → **Add Service Account**) ### Authenticate by Service Account Token 1. Navigate to Settings > Integrations 2. Click "Connect Asana" 3. Enter your Asana Service Account token 4. Verify the connection :::warning A Service Account token has organization-wide access to all data, including private user data. Treat it as a highly privileged secret. ::: ## Create User Integration 1. Click `Connect Now` in the User Integrations section 2. You will be redirected to Asana to authorize 3. Grant Fours access to your Asana account 4. Return to Fours and verify the connection ## Fours AI Tools When Asana is connected, the Fours AI agent can manage work in Asana through Fours' built-in tools (43 actions). Capabilities are grouped below. > **Org-level and user-level**: Both are supported; user-level takes precedence when both are connected. | Capability | What the agent can do | |------------|-----------------------| | **Tasks** | Create, read, update, and delete tasks and subtasks, and search a workspace (e.g. `create-task`, `update-task`, `search-tasks-in-workspace`) | | **Projects** | Manage projects and task–project membership (e.g. `create-project`, `add-project-to-task`) | | **Sections** | Organize tasks into project sections (e.g. `create-section`, `list-tasks-for-section`) | | **Tags** | Manage tags and attach or detach them on tasks (e.g. `create-tag`, `add-tag-to-task`) | | **Stories & comments** | Add and read comment threads on tasks (e.g. `create-story-on-task`, `list-stories-for-task`) | | **Workspaces, teams & users** | Read org structure and the connected account (e.g. `get-account`, `list-workspaces`, `list-users-for-workspace`) | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration from Fours. :::warning This does not delete your data in Asana. For the org Service Account token, revoke or rotate it in the Asana Admin console → Apps → Service Accounts. ::: --- Source: https://doc.fours.com/integrations/ashby/ # Ashby Connect Ashby so Fours AI can work with your candidates, applications, and job postings. --- ## Overview [Ashby](https://www.ashbyhq.com) is an applicant tracking and recruiting platform covering sourcing, interviewing, and hiring analytics. Connecting it lets the Fours AI agent read and update your recruiting pipeline — candidates, applications, interviews, and job postings — from a Fours workflow or chat. ### Org-Level vs User-Level > **Org-Level**: Supported. One Ashby API key serves the whole organization. > > **User-Level**: Not applicable. Ashby authenticates with an API key only — it has no OAuth flow of any kind — so there is nothing an individual user could sign in to. Every Fours user in your organization shares the org connection. ### How the connection works Ashby authenticates with HTTP Basic, where the API key *is* the username and the password is empty. Fours stores the key and builds that header for you, so there is only one field to fill in. ```d2 shape: sequence_diagram admin: "Your Fours admin" suger: "Fours" ashby: "Ashby" agent: "Fours AI agent" admin -> suger: "Paste the Ashby API key" suger -> ashby: "Check the key before saving the connection" ashby -> suger: "Accepted — connection stored" { style.stroke-dash: 4 } rejected: "if the key is wrong or revoked" { ashby -> suger: "Rejected — the connect fails here, not at the first tool call" { style.stroke-dash: 4 } } agent -> suger: "Run an Ashby tool" suger -> ashby: "HTTP Basic — the key as the username, blank password" ashby -> agent: "Candidates, applications, interviews, postings" { style.stroke-dash: 4 } ``` ## Create Integration (Org-Level) ### Prerequisites - An Ashby account on a plan that includes API access. - Permission to create an API key in Ashby (**Admin** settings). - The Fours **Admin** role — connecting, disconnecting, and running an integration's actions are all admin-only in Fours. ### Authenticate by API key 1. In Ashby, go to **Settings → Integrations → API** and generate a new API key. Copy it — Ashby shows it once. 2. Grant the key the module permissions you want Fours to have. Ashby scopes API keys per module (Candidates, Jobs, Interviews, and so on), so a key missing a module makes every tool for that module fail. Grant read access at minimum, plus write access for anything you want the agent to change. 3. In the Fours console, open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) and click **Connect** on **Ashby**. 4. Paste the key into the single **API Key** field and save. Paste the raw key, not a base64 string — Fours builds the Basic header itself. There is no separate username or password to supply. :::info Fours checks the key against Ashby rather than storing it blind — Ashby is one of the few connectors that offers an endpoint for this. A wrong or revoked key is reported as an error instead of sitting in a connection that looks healthy and fails on its first tool call. The check confirms the key is valid; it cannot confirm you granted it every module the tools you plan to use will need. ::: ## Fours AI Tools When Ashby is connected, the Fours AI agent can work your recruiting pipeline through Fours' built-in tools (23 actions). > **Org-level**: All tools run under the org API key, so what the agent can see and change is exactly what that key's module permissions allow. | Capability | What the agent can do | |------------|-----------------------| | **Candidates** | Create, read, update, and list candidates (e.g. `create-candidate`, `update-candidate`, `list-candidates`) | | **Applications** | Create, read, update, and list applications, and move one between stages or sources (e.g. `change-application-stage`, `change-application-source`) | | **Jobs & postings** | Read and list jobs and their public postings (e.g. `get-job`, `list-job-postings`) | | **Interviews** | Read and list scheduled interviews (e.g. `get-interview`, `list-interviews`) | | **Notes** | Add notes to a candidate record (`create-note`) | | **Org data** | Read and list departments, sources, and users (e.g. `list-departments`, `list-sources`, `list-users`) | :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration Editing is not supported. To rotate the key or point Fours at a different Ashby account, delete the integration and create it again. ## Delete Integration Click the 🗑️ button next to **Ashby** in the **Integrations** list. The stored key is destroyed with the integration record. Any Fours workflow or agent that depended on Ashby tools stops working immediately. Revoke the key in Ashby too if you want to cut access from that side. --- Source: https://doc.fours.com/integrations/atlassian/ # Atlassian ## Overview Atlassian provides a suite of collaboration tools including Jira for issue tracking and project management and Confluence for documentation and knowledge management. By connecting Fours to Atlassian, the Fours AI agent can create and update Jira issues and Confluence pages and automate your team's project and documentation workflows. ### Org-Level vs User-Level > **User-Level Only**: Atlassian integration is configured per user. Each user authenticates with their own Atlassian account via OAuth. ## Create User Integration ### Authenticate 1. Navigate to Settings > Integrations > User Integrations 2. Click `Connect Now` in the Atlassian section 3. You will be redirected to Atlassian to authorize 4. Grant access to your Atlassian workspace 5. Return to Fours to confirm the connection :::note Each user connects their own Atlassian account. The integration uses OAuth to authenticate with Atlassian. ::: ## Fours AI Tools When Atlassian is connected, the Fours AI agent can work across Jira and Confluence through Fours' built-in tools (78 actions). Capabilities are grouped below. > **User-level**: Each user connects their own Atlassian account; multi-site access is resolved via the connected account's accessible resources. | Capability | What the agent can do | |------------|-----------------------| | **Jira issues** | Create, read, update, link, and search issues with JQL (e.g. `jira-create-issue`, `jira-search-issues`, `jira-create-issue-link`) | | **Jira workflow & comments** | Transition issues and add comments, worklogs, watchers, and attachments (e.g. `jira-transition-issue`, `jira-add-comment`, `jira-add-worklog`) | | **Jira projects & metadata** | Read projects, fields, statuses, priorities, and issue types (e.g. `jira-list-projects`, `jira-list-fields`, `jira-get-create-issue-metadata`) | | **Confluence pages & blog posts** | Create, update, and search pages and blog posts (e.g. `confluence-create-page`, `confluence-update-page`, `confluence-search-content`) | | **Confluence comments & properties** | Add footer and inline comments and content properties (e.g. `confluence-create-footer-comment`, `confluence-create-inline-comment`) | | **Confluence spaces & attachments** | Read spaces and manage attachments (e.g. `confluence-list-spaces`, `confluence-list-attachments`) | | **Account & sites** | Read the connected user and accessible Atlassian sites (e.g. `get-account`, `get-accessible-resources`) | ## Edit Integration Editing not supported. Delete and recreate. ## Delete Integration Deleting removes the integration and immediately revokes access to Atlassian. :::warning Deleting the integration will remove access to Atlassian immediately. Check Atlassian documentation for any cleanup steps regarding issues, pages, or repositories created by Fours. ::: --- Source: https://doc.fours.com/integrations/auth0/ # Auth0 ## Overview Auth0 is an identity and access management platform that provides authentication, authorization, and single sign-on capabilities. Integrate with Auth0 to enable secure SSO for your Fours organization using your existing Auth0 configuration. ### Org-Level vs User-Level > **Org-Level**: Uses OAuth/OIDC configuration for organization-wide SSO. Best for enterprise identity management. > > **User-Level**: Not applicable - Auth0 is an enterprise SSO solution. ## Create Integration (Org-Level) ### Prerequisites - Auth0 account with application management capabilities - Auth0 domain and client credentials - Admin access to configure OAuth/OIDC application ### Authenticate by OAuth/OIDC 1. Navigate to Settings > Integrations 2. Click "Connect Auth0" 3. Enter your Auth0 domain (e.g., your-tenant.auth0.com) 4. Enter your Auth0 Client ID 5. Enter your Auth0 Client Secret 6. Configure the callback URL in your Auth0 application 7. Verify the connection ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration from Fours. :::warning This does not delete your Auth0 application or user data. Remember to also remove the Fours application from your Auth0 dashboard if you no longer need the connection. ::: --- Source: https://doc.fours.com/integrations/avalara/ # Avalara ## Overview Avalara AvaTax is a cloud tax-compliance engine that calculates sales, use, and VAT tax in real time and validates addresses for accurate jurisdiction assignment. Connect Avalara to Fours so the Fours AI agent can compute tax on invoices and sales orders, commit or void tax transactions, validate customer addresses, and look up tax codes and companies on your Avalara account — keeping marketplace billing tax-compliant. ### Org-Level vs User-Level > **Org-Level Only**: Avalara connects at the organization level using your Avalara Account ID and License Key. The connection is shared across your organization. ## Create Integration (Org-Level) ### Prerequisites - An Avalara AvaTax account - Your Avalara **Account ID** and a **License Key** (Avalara → **Settings → License and API Keys**) - Your **Company Code** (used per transaction, not in the connection form) ### Authenticate by License Key 1. Navigate to Settings > Integrations 2. Click **Connect Avalara** 3. Fill in three fields: | Field | What it is | | ----- | ---------- | | **Account ID** | Your Avalara account identifier. | | **License Key** | The key from Avalara → **Settings → License and API Keys**. Stored as a secret. | | **Avalara Client** | Identifies Fours in AvaTax's request logs. **This value is ours, not yours** — it ships pre-filled with the correct default, so leave it alone unless Fours support asks you to change it. | 4. Save, then click **Verify** to confirm the connection :::note The integration connects to Avalara **production** (`https://rest.avatax.com`) by default. Advanced setups can target the Avalara **sandbox** (`https://sandbox-rest.avatax.com`) via the environment setting. ::: ## Fours AI Tools When Avalara is connected, the Fours AI agent can run tax operations through Fours' built-in tools (13 actions). Capabilities are grouped below. > **Org-level**: Tools run against the organization's connected Avalara account. | Capability | What the agent can do | |------------|-----------------------| | **Tax calculation** | Estimate tax on a sales order or create a committed transaction from invoice data (e.g. `calculate-tax`, `create-transaction`) | | **Transaction lifecycle** | Commit or void an existing transaction (e.g. `commit-transaction`, `void-transaction`) | | **Address validation** | Validate and normalize an address (e.g. `resolve-address`) | | **Reference & account data** | List companies and tax codes, and read the connected account (e.g. `list-companies`, `list-tax-codes`, `get-account`) | | **Transaction lookup** | Read one transaction or list many (e.g. `get-transaction`, `list-transactions`) | | **Adjustments** | Adjust an existing transaction (e.g. `adjust-transaction`) | | **Jurisdiction reference** | List the company's locations and nexus registrations (e.g. `list-locations`, `list-nexus`) | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration and revokes the stored Avalara credentials from Fours. :::warning This does not affect any transactions already recorded in Avalara. You may also want to revoke the License Key in Avalara (**Settings → License and API Keys**). ::: --- Source: https://doc.fours.com/integrations/aws-ace-migration-from-s3-to-api/ # AWS ACE Migration S3 to Partner Central API ## Overview This guide explains how to migrate your existing **S3-based AWS APN integration** to the **Partner Central API (ACE API)**. The migration ensures your integration uses the latest API-based method, providing improved stability, real-time updates, and full support for AWS ACE features. The migration process includes: - Updating IAM role permissions using AWS CloudFormation. - Upgrading the integration in the Fours Console. - Verifying the updated integration. - Running inbound and outbound synchronization to complete the migration. ## 1. Prerequisites Before starting the migration, make sure you have: - An **AWS Seller Account** linked to your APN account. - Access to **AWS Partner Central** with an Alliance Lead or Cloud Admin role. - An **AWS IAM administrator** who can configure roles via CloudFormation. - An **existing IAM role** used for your current S3-based integration. :::warning If you don’t have an IAM administrator available, please engage your internal AWS admin team before proceeding. ::: ## 2. Migration Steps ### Step 1: Open Partner Central API Configuration via Console UI 1. In the **Fours Console**, go to **[Integrations](https://console.suger.io/settings?tab=integrations) → AWS ACE**. 2. Click **Edit** on your existing AWS ACE integration. > Edit button on the existing AWS ACE integration 3. Click **Upgrade to Partner Central API** in the top-right corner. > Upgrade to Partner Central API button on the AWS ACE integration 4. Click **Update Existing IAM Roles via CloudFormation**. This will redirect you to the AWS **CloudFormation Console**. > Update Existing IAM Roles via CloudFormation button ### Step 2: Configure Partner Central API Permissions 1. On the redirected **CloudFormation** page, review the settings. - Check the box **“I acknowledge that AWS CloudFormation might create IAM resources with custom names.”** - Click **Create stack**. > Create stack step in the AWS CloudFormation console :::info By running the CloudFormation update, all required AWS managed policies are automatically attached to the existing IAM Role. This ensures Fours has the correct permissions to access the ACE Partner Central API without any additional manual configuration. ::: 2. Wait until the stack status changes to **CREATE_COMPLETE**. > CloudFormation stack status showing CREATE_COMPLETE :::info This indicates that the IAM role permissions have been updated successfully. ::: ### Step 3: Verify Integration 1. Return to the **Fours Console → Settings → Integrations → AWS ACE**. 2. Click **Apply Upgrade** to update and verify the integration. > Apply Upgrade button for the AWS ACE integration :::info Once verified, the system will automatically create an EventBridge rule and an API destination in your AWS account to listen for APN opportunity changes. Verification ensures that your IAM role and API connection are working correctly before moving on to data synchronization. ::: ### Step 4: Perform Data Synchronization 1. In the **Fours Console → [Co-Sell](https://console.suger.io/cosell) → AWS ACE**, click the **Inbound Sync** button to pull opportunity data from **APN** into **Fours**. 2. Go to **Settings → Integrations → AWS ACE → Operations** and wait until the inbound sync **status** changes to **Completed**. :::note Duration _This typically takes a few minutes; the actual duration depends on the number of APN opportunities being fetched._ ::: > AWS ACE Operations tab showing sync status > Inbound sync operation with Completed status :::info This confirms the data has been synchronized successfully. ::: 3. Next, return to **Co-Sell → AWS ACE** and click the **Outbound Sync** button to push data from **Fours** back to your **CRM Partner**. 4. Again, check the **Operations** page and wait until the outbound sync **status** shows **Completed**. :::note Duration _This usually takes a few minutes; the duration depends on the number of records to push and API limits._ ::: Both **inbound** and **outbound** sync must be completed successfully to ensure data consistency between **APN** and **Fours**. --- Source: https://doc.fours.com/integrations/aws-billing/ # AWS Billing ## Overview Connect Fours to AWS Billing to enable consolidated cloud cost management and billing operations. This integration allows you to sync billing data, manage costs, and streamline financial operations across your AWS infrastructure. > **Org-Level Only**: This integration uses OAuth for organization-wide billing access. User-level billing integration is not supported. ## Create Integration ### Prerequisites - AWS account with billing access - AWS Organization master account or linked account access - Appropriate billing permissions (Billing and Cost Management) ### Authenticate 1. Navigate to Settings > Integrations 2. Click "Connect AWS Billing" 3. Authorize via OAuth with your AWS account 4. Configure billing data access scope 5. Verify connection ## Edit Integration Editing not supported. Delete and recreate. ## Delete Integration Deleting removes the integration. :::warning This may affect billing data synchronization and cost reporting. ::: --- Source: https://doc.fours.com/integrations/aws-partner-network-api/ # AWS Partner Central API ## Overview This guide walks you through setting up the AWS Partner Central integration using the **Partner Central API**. With this integration, you can seamlessly sync opportunities, share referrals, and manage co-sell engagements with AWS. ## Prerequisites - **Identity and Access Management (IAM) administrator** - handles permissions and technical setup in AWS (e.g. IAM roles, policies, or SSO). - **AWS Partner Central Alliance Lead or Cloud Administrator** - the primary account owner in **AWS Partner Central**, with authority to accept **AWS Partner Network** terms. - **CRM access** - AWS ACE co-sell works with **Salesforce**, **HubSpot**, or **Microsoft Dynamics 365** as your CRM. ## 1. Link AWS Seller Account to APN ### Step 1. Identify an AWS account to link Before linking, your **Alliance Lead (or Cloud Admin)** and **IAM Administrator** should select the AWS account that will be connected to Partner Central. - **General recommendation** - AWS recommends linking an account dedicated to APN engagements. - If your company has multiple AWS accounts, consider selecting the one that: - You use to sign in to AWS Partner Central - Represents your global business - Serves as the primary account for administrative tasks - If you are an **AWS Marketplace seller**: - You may choose to link a Marketplace seller account. - If you own multiple Marketplace accounts, select your primary account such as the one with the most transactions. ### Step 2. Grant Access to Your Team Before linking your AWS account, ensure that the right permissions are in place. This step is handled by your IAM Administrator. - The **IAM Administrator** must configure IAM policies so that Partner Central users (Alliance Lead or Cloud Admin) have the necessary access to complete the account linking process. - Follow the AWS official guide: [Account Linking Prerequisites](https://partnercentral.awspartner.com/partnercentral2/s/article?category=Introductory_resources&article=AWS-Partner-Central#Pre-requisite:%20Granting%20IAM%20permissions%20(Option%201)) → **Granting IAM Permissions** for the latest instructions on which IAM policies are required. :::tip In most cases, this involves granting read-only IAM permissions and allowing Partner Central to create the required roles (e.g., Cloud Admin, Alliance, ACE). We recommend letting your IAM Administrator review the official AWS guide to ensure compliance with your company’s security practices. ::: ### Step 3. Start the Linking Process 1. Sign in to [AWS Partner Central](https://partnercentral.awspartner.com/partnercentral2/s/) with an Alliance Lead or Cloud Admin role. 2. On the homepage, click **Link Account**. > AWS Partner Central homepage with Link Account button 3. Click **Continue to Account Linking** once Step 2 has been completed. > Continue to Account Linking confirmation step 4. Click **Initiate Account Linking** > Initiate Account Linking button in AWS Partner Central ### Step 4. Sign in to Your AWS Account 1. Sign in with AWS account ID along with its IAM user name, and Password. 2. If your organization uses **single sign-on (SSO)**, use those credentials to sign in to your AWS account first, then sign in to **AWS Partner Central**. > AWS single sign-on login screen ### Step 5. Provide Legal Business Information :::note This step is **required only** if the selected account has not yet been registered as a **Marketplace seller**. ::: 1. Enter your **Legal Business Name** and click **Next**. 2. Doing this will register your account as a seller in the background, but: - Your account will not become public-facing. - You will not be able to list products until you complete the full [Marketplace seller registration process](https://docs.aws.amazon.com/marketplace/latest/userguide/seller-registration-process.html) separately. 3. Regional note: If your company is under AWS India (Amazon Web Services India Private Limited), you can skip this step and proceed directly by clicking Next. > Legal Business Name entry step in account linking ### Step 6. Assign IAM Roles 1. **(Recommended)** Check all the boxes to assign IAM roles (eg. Cloud Admin, Alliance Team, and ACE team) to existing Cloud Admins, Alliance Team, and ACE users in AWS Partner Central. > Assign IAM roles checklist during account linking :::info - This ensures that your Partner Central users have the correct permissions from the start. Bulk assignment vs. manual mapping: Bulk assignment is only available during the linking workflow. You can still assign or adjust IAM roles later, but it must be done manually after linking. - Standard role creation: Cloud Admin, Alliance Team, and ACE Team roles are created automatically once the account is linked — even if you don’t assign them during this step. - Role cleanup: If any roles are unnecessary, your IAM Administrator can remove them in the AWS IAM console. ::: 2. Click **Next** button. ### Step 7. Verify Linking Status 1. Verify account linking status is green and states **Completed** under both sections. 2. Click on **Refresh status** button to see updates on IAM roles mapping progress. > Account linking status showing Completed ## 2. Configure Integration in Fours ### Step 1. Access the Fours Integrations page 1. In the **Fours Console**, go to **[Integrations](https://console.suger.io/settings?tab=integrations) → AWS ACE**. 2. Click **Connect Now** on the AWS ACE card. > AWS ACE integration card with Connect Now button ### Step 2. Create IAM role via CloudFormation 1. Click **Create IAM role via CloudFormation**. You will be redirected to **CloudFormation** in the linked AWS seller account. > Create IAM role via CloudFormation button in Fours 2. Sign in with AWS account ID along with its IAM user name, and Password. :::info If your organization uses single sign-on (SSO), use those credentials to sign in to your AWS account first, then sign in to AWS Partner Central. ::: 3. Check the acknowledgment box and click **Create Stack**. All required fields are pre-populated. > CloudFormation Create Stack confirmation with acknowledgment checkbox ### Step 3. Verify the IAM Role Policies 1. Find the created IAM role under the **Resources** tab or by navigating to IAM → Roles. > IAM role listed under CloudFormation Resources tab > CloudFormation resources table with created IAM role 2. The IAM role is automatically created with these AWS managed policies: - `AmazonEventBridgeFullAccess` & `IAMReadOnlyAccess`: allow EventBridge rules and webhooks for APN opportunity changes. - `AmazonS3FullAccess`: optional, for S3-bucket-based integration. - `AWSMarketplaceSellerFullAccess` & `AWSPartnerCentralFullAccess`: enable linking APN opportunities with Marketplace private offers and Marketplace product listings. ### Step 4. Connect IAM role to Fours 1. Copy the **ARN** of the generated role. 2. Paste it into the **Integration IAM Role ARN** field in Fours. 3. Click **Create**. > Integration IAM Role ARN field in Fours ### Step 5. Verify integration 1. Click **Verify** in Fours. > Verify button for AWS ACE integration 2. When verification succeeds, the status will show **Connected**. :::info Once verified, the system will automatically create an EventBridge rule and an API destination in your AWS account to listen for APN opportunity changes. Verification ensures that your IAM role and API connection are working correctly before moving on to data synchronization. ::: ### Step 6. Perform Data Synchronization 1. In the **Fours Console → [Co-Sell](https://console.suger.io/cosell) → AWS ACE**, click the **Inbound Sync** button to pull opportunity data from **APN** into **Fours**. 2. Go to **Settings → Integrations → AWS ACE → Operations** and wait until the inbound sync **status** changes to **Completed**. :::note Duration _This typically takes a few minutes; the actual duration depends on the number of APN opportunities being fetched._ ::: > AWS ACE Operations tab in Fours integrations > Inbound sync operation status showing Completed :::info This confirms the data has been synchronized successfully. ::: 3. Now you are all set! ## Troubleshooting | Issue | Cause | Resolution | | --- | --- | --- | | Error: `Record not editable` | You tried to update an opportunity that is currently under ACE review. | These opportunities cannot be edited until they are validated by AWS. | | Errors: `Missing IAM Role Mapping`, `Missing Permission`, or `Access denied` | An AWS Partner Central user wasn't mapped to an IAM role. | Ask your Alliance Lead or Cloud Admin to map the appropriate role to the user. | | Integration progress is not updating in the AWS Partner Central portal | The integration process is unverified or unfinished. | Verify the account linking status is green and shows **Completed** under both sections, then click **Refresh status** to see the latest updates on your IAM role mapping progress. | | A connected partner shows as `AWS Account ` instead of its company name in **Share with Partner** | Fours could not look the partner's name up in AWS Partner Central: its profile is unpublished or deleted, the integration's IAM role lacks permission, or the lookup timed out, failed, or returned no name. | Fours retries on its partner sync, which runs every 6 hours, and keeps any name it has already found. If every partner stays this way across syncs, check that the integration's IAM role still has `AWSPartnerCentralFullAccess` (see [Step 3](#step-3-verify-the-iam-role-policies)). | ## Frequently Asked Questions **How long does data synchronization take?** This typically takes a few minutes, though the actual duration depends on the number of APN opportunities being fetched. **Should I use the legacy S3 integration?** No. The S3-based integration is **deprecated** — AWS no longer provisions it for new users (unavailable since 2024), so new S3 connections cannot be created. Start with the AWS Partner Central API integration described on this page. Existing S3 connections remain supported for now; see the [S3-to-API migration guide](/integrations/aws-ace-migration-from-s3-to-api/). ## Delete Integration To delete the integration, simply click the 🗑️ button in the **Integrations** list. Once the deletion is triggered, all integration information, including the access token, will be immediately and permanently deleted from Fours. :::warning Please note: once deleted, integration data cannot be recovered. ::: --- Source: https://doc.fours.com/integrations/aws-partner-network-s3/ # Legacy Partner Central S3 Integration :::warning ⚠️ This guide describes the **legacy S3-based integration**, which is **deprecated**. AWS no longer provisions S3-based CRM integrations, and it has been unavailable to new users since 2024, so **new S3 connections cannot be created**. See the [AWS Partner Central CRM guide](https://docs.aws.amazon.com/partner-central/latest/crm/s3-config.html) for AWS's current status. - **New integrations:** use the [AWS Partner Central API](https://doc.fours.com/integrations/aws-partner-network-api/) integration instead. - **Existing S3 connections:** remain supported for now. Migrate at your earliest convenience with the [S3-to-API migration guide](/integrations/aws-ace-migration-from-s3-to-api/). ::: Sync leads & opportunities with AWS Partner Central for co-sell. --- ## Overview By integrating with programs such as [APN Customer Engagement](https://aws.amazon.com/partners/programs/ace/) (ACE) and ISV Accelerate, ISV/Sellers can scale their co-sell programs more effectively. The integration streamlines the process of managing information about leads and opportunities, reducing manual efforts and eliminating the need to maintain data in two separate systems, such as the Salesforce CRM and AWS Partner Central. Through the integration, ISV/Sellers can easily manage new opportunities and leads. They can accept new opportunities and leads, receive updates on them from AWS, and send new opportunities and updates on their leads and opportunities to AWS. All of these actions are supported by an AWS-managed S3 bucket, which acts as an intermediary in the bi-directional exchange of files. ## Request CRM Integration on AWS Partner Central Before integrating your ACE pipeline with Fours, you first need to initiate an onboarding request on [CRM Integration self-service portal](https://partnercentral.awspartner.com/partnercentral2/s/acecrmintegration). :::info - This can only be done by **Alliance Lead** - This process involves creating **AWS IAM Roles** so you may need to involve your **Cloud Ops** if you do not have the permissions on your AWS Console. ::: 1. **[AWS Console] Create AWS IAM Role** Create two empty IAM roles, one for sandbox/test environment, and the other for production environment. The name can be arbitrary. A common name is `APN-ACE-{company}-AccessRole-beta` and `APN-ACE-{company}-AccessRole-prod`. You can create the roles with [Fours' CloudFormation quick-create stack](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/quickcreate?templateURL=https://suger-public-access-bucket.s3.us-west-2.amazonaws.com/suger-aws-ace-iam-stack-template.json&stackName=AceAccessRole). The only purpose of these roles is to access the S3 buckets which are created and owned by APN. They won't need any access to your company's resources. 2. Navigate to [CRM Integration self-service portal](https://partnercentral.awspartner.com/partnercentral2/s/acecrmintegration) and click `Initiate Onboarding Request` button on the bottom. 2. **Step 1 - Enter basic information** - Partner CRM system - Choose Salesforce or HubSpot. - What solution would you be using to integrate your CRM with APN? - Choose "Third Party Solution". - Name of the third party solution provider - Fours - Estimated integration start date - choose the next Monday or the date you prefer. 3. **Step 2 - Enter partner contacts** Third party contact: - Email: `support@suger.io` - Partner Role: Third Party Staff 4. **Step 3 - Enter the ARN for the role you created** 5. **Step 4 - Set up Sandbox** APN will set up a sandbox bucket, and generate a policy JSON doc to access it. Copy the JSON content and attach it to the sandbox role you created in AWS console. Then you can mark it as completed. 6. **Step 5 - Set up Production** After you mark implementation completed and UAT passed, proceed to the next step and APN will provision the production bucket, with another JSON policy doc. Similar to the sandbox, copy & attach it to the production role in AWS console. 7. **Step 6 - Launch** Click the "Submit" button. APN will show that the CRM integration has been "Launched". After all the steps, you will now have: 1. A production S3 bucket provisioned and owned by APN. 2. An IAM role that have access to the bucket. > IAM roles created for the AWS ACE S3 integration The sandbox role is created only because APN requested for it. It will not be used by Fours. :::info - The bucket name contains your "Partner ID" and region as well. The format is `ace-apn-{PartnerID}-prod-{Region}`. E.g., if your bucket name is `ace-apn-12345678-prod-us-west-2`, then: - Your "Partner ID" is `12345678` - Your Bucket region is `us-west-2` ::: Now you need to create the ACE integration on Fours Console to delegate the user/role to Fours, so our automated pipelines can manage it for you. ## Create Integration on Fours 1. Visit the [integration page of Fours console](https://console.suger.io/settings?tab=integrations), click the button 'Connect' in the `AWS ACE` integration card. There are four fields to input. - **AWS IAM Role ARN**: It is `APN-ACE-{partnerName}-AccessRole-prod` created in the previous step. - **AWS S3 Bucket Name**: The Name of the S3 bucket provisioned by AWS ACE team. - **AWS Partner ID**: The number in your bucket name. - **AWS S3 Bucket Region**: The AWS region of the S3 bucket provisioned by AWS ACE team - also in the bucket name. 2. After the connection is created, click the button `Verify` to finish the verification of the AWS ACE integration. Then all set. ## Provide More Details After the integration is created and verified, we need to collect a little more information: - ACE Program - Solution Offering You need to click the `🖊️Edit` button on ACE integration and input the information there: 1. > ACE Program field in the AWS ACE integration edit dialog 2. > Solution Offering field in the AWS ACE integration edit dialog ### Solution Offering Since November 2023, ACE requires all partners to specify "Solution Offerings" when sharing opportunities with AWS. You can register or check your offerings at [Partner Central](https://partnercentral.awspartner.com/partnercentral2/s/offeringlistview). Make sure the "Offering status" is shown as ✅Active. > Active offering status in AWS Partner Central Open the offering, **copy** the "Offering ID" located at the top left: > Offering ID field in AWS Partner Central Then, input the offering ID and hit `Enter`, and click `Save`. ## Delete Integration If you need to delete the [AWS Partner Central](https://aws.amazon.com/partners/) integration, you can do so like any other integration. Once the deletion is triggered, all integration information, including the access token, will be immediately and permanently deleted from Fours. :::warning Please note that there is no time window or any means of recovering the deleted data. ::: ## Next steps :::info - [AWS Partner Central API Integration Guide](/integrations/aws-partner-network-api/) ::: --- Source: https://doc.fours.com/integrations/azure-cosell/ # Azure Co-Sell ## Overview Connect Fours to Azure Co-Sell to manage co-selling opportunities and partnerships with Microsoft. The Azure Co-Sell program enables ISVs and partners to sell jointly with Microsoft sales teams through the **Microsoft AI Cloud Partner Program** (formerly Microsoft Partner Network / MPN) — the co-sell motion Microsoft previously ran through its One Commercial Partner (OCP) organization — managed in **Microsoft Partner Center**. ### Org-Level vs User-Level > **Org-Level Only**: This integration is org-level only. Uses OAuth for organization-wide co-sell program access. > > **User-Level**: Not supported for Azure Co-Sell integrations. ## Create Integration (Org-Level) ### Prerequisites - Microsoft AI Cloud Partner Program membership with a valid **Partner ID** (formerly Microsoft Partner Network / MPN) - A **Microsoft Entra ID** tenant (formerly Azure Active Directory / AAD) - Enrolled in the Azure Co-Sell program - Appropriate roles in Microsoft Partner Center ### Authenticate 1. Navigate to Settings > Integrations 2. Click "Connect Azure Co-Sell" 3. Authorize via OAuth with your Microsoft partner account 4. Configure co-sell opportunity sync settings 5. Verify connection ## Edit Integration Microsoft co-sell runs on your Azure Marketplace integration. To change its co-sell settings, open that integration's **⋯** menu, choose **Edit**, and use **Enable Cosell** and the co-sell options that appear beneath it. To replace an expiring client secret, an Admin chooses **⋯ → Update Credential** and pastes the new secret; the tenant, client ID, Partner Center sign-in and co-sell settings are kept, and the integration is verified again — see [Update Credential](/azure-marketplace/integration/#update-credential). Don't delete and recreate the integration to change either. ## Delete Integration Deleting removes the integration. :::warning This may affect active co-sell opportunities and partner relationships. ::: --- Source: https://doc.fours.com/integrations/baseten/ # Baseten Connect your Baseten API key to run Fours' AI features on the models you serve on Baseten. --- ## Overview Baseten is an AI model provider (category: AI). By connecting your own Baseten API key (bring-your-own-key), the models available to your Baseten account become selectable in Fours' model picker — for Insulin agents, chat, and inference. API usage is billed directly by Baseten to your account; Fours does not charge for these models. ### Org-Level vs User-Level - **Org-Level**: the key is shared across your organization. Its models are available to organization-level agents and to members of the org. Connecting requires an organization admin. - **User-Level**: the key is personal to your workspace. Its models are available to your own user-level agents and personal Insulin. --- ## Create Integration 1. Navigate to the [Fours Console Integrations](https://console.suger.io/settings?tab=integrations) page. 2. Find the **Baseten** integration and click **Connect**. 3. Choose the level — **Organization** (shared) or **User** (personal). 4. Paste your **Baseten API Key** and click **Save credentials**. Fours verifies the key with Baseten before storing it, so an invalid key is rejected at connect time rather than surfacing later as a failed model run. > Generate an API key in your Baseten account at [baseten.co](https://www.baseten.co/) (**API keys**). :::info After connecting, open any model picker — an agent's **Default Model**, or **Insulin model settings** — and Baseten's models appear, with verified models grouped first and each entry attributed to Baseten. ::: ## Edit Integration Editing the API key is not supported. To change the key, delete the integration and create a new one. ## Delete Integration You can delete the Baseten integration at any time. This permanently removes the stored credential. Any agent pinned to a Baseten model then shows that model as **unavailable** with a reconnect prompt until you reconnect Baseten or pick another model — Fours never silently substitutes a different model. :::info Fours registers no Baseten embedding model, so no Baseten option appears in the knowledge-base embedding chooser — this integration serves chat and inference models. Knowledge-base embeddings use a Fours-hosted model (organization knowledge bases only) or a connected OpenAI, Gemini, OpenRouter, DeepInfra, Fireworks, or Together provider — see [Knowledge Bases](../../insulin/knowledge-base/). ::: --- Source: https://doc.fours.com/integrations/bigquery/ # BigQuery ## Overview Allow Fours to query and manage data in Google BigQuery. Google BigQuery is a fully-managed, serverless, highly-scalable cloud data warehouse and analytics platform offered by Google Cloud Platform (GCP). It is designed to handle massive datasets and enable fast SQL queries using a pay-as-you-go pricing model. By connecting Fours to Google BigQuery, you can build customized automation workflows for usage metering, financial reports, or notifications. ### Org-Level vs User-Level > **Org-Level**: Uses a GCP service account for organization-wide BigQuery access. Best for company-wide data analytics. > > **User-Level**: Not applicable — BigQuery is an org-level integration only. ## Create Integration (Org-Level) ### Prerequisites - GCP project with BigQuery API enabled - Service account with BigQuery Admin role or appropriate dataset permissions ### Authenticate by Service Account 1. [Create a service account](https://docs.cloud.google.com/iam/docs/service-accounts-create) in your target GCP project for BigQuery service. 2. Grant appropriate BigQuery permissions to the service account. Some suggested options include: - BigQuery Admin - BigQuery User - BigQuery Data Viewer 3. [Create a service account key](https://docs.cloud.google.com/iam/docs/keys-create-delete#creating) and download the associated JSON file. 4. Enter the service account email and upload the JSON key in Fours. ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the BigQuery API directly. > **Org-level only**: BigQuery tools use the org-level service account credentials. | Tool | Description | |------|-------------| | `googlebigquery_list_datasets` | List all BigQuery datasets in the configured GCP project | | `googlebigquery_list_tables` | List all tables in a BigQuery dataset | | `googlebigquery_get_table_schema` | Get the schema (column names, types, descriptions) and metadata for a table | | `googlebigquery_run_query` | Run a standard SQL query and return results | ## Edit Integration Editing is not supported. To change configuration, delete and recreate. ## Delete Integration Deleting removes the integration and revokes access. No recovery window. :::warning You must also remove the service account permissions in GCP Console. ::: --- Source: https://doc.fours.com/integrations/chargebee/ # Chargebee Link your Chargebee instance to Fours to automate subscription and revenue operations, and to report the metered overage Chargebee prices onward to the cloud marketplaces. --- ## Overview [Chargebee](https://www.chargebee.com) is a subscription management and recurring billing platform that empowers businesses to automate revenue operations. It offers comprehensive billing and revenue management solutions for modern SaaS and subscription-based businesses. If you bill metered usage through Chargebee, Fours can also carry it onto the marketplace bill. With **Enable Auto Report Usage** on, Fours reads the overage Chargebee has priced for each linked buyer every hour and reports it to that buyer's cloud marketplace entitlement, so nobody has to key it into the marketplace by hand. See [How the usage sync works](#how-the-usage-sync-works). ### Org-Level vs User-Level > **Org-Level**: Uses an API key for organization-wide access. Best for company-wide subscription and billing management. > > **User-Level**: Not typically supported for billing integrations. ## How the usage sync works | | | | --- | --- | | **Direction** | One-way: Chargebee → Fours → cloud marketplace. Fours reads subscriptions, usage charges and invoices from Chargebee and reports the amounts onward as [usage record groups](/metering/usage-metering/). The sync never writes to Chargebee. | | **Source of truth** | Chargebee owns the priced overage and the invoices. Fours owns the link between a buyer and a Chargebee customer, the mapping to marketplace dimensions, and the records it reports. | | **Scope** | Organization-level. Only buyers that carry a Chargebee customer ID are synced — see [Connect Chargebee Customer](#connect-chargebee-customer). | | **Schedule** | Every hour at **5 minutes past the hour**, for a `VERIFIED` integration with **Enable Auto Report Usage** on and **Billing Mode** set to `amount`. | | **What is reported** | Money, not units. Every amount goes out on the single source dimension key `chargebee` — see [Billing Mode](#billing-mode). | ```d2 direction: right chargebee: "Chargebee" { counter: "Usage charges\nwhile the window is open" invoice: "Invoice\nafter the window closes" voided: "Voided invoice" } suger: "Fours" { record: "Usage record group\nkey: chargebee" credit: "Credit on the\nentitlement" } marketplace: "Cloud marketplace\nentitlement" chargebee.counter -> suger.record: "hourly: growth since the last read" chargebee.invoice -> suger.record: "settle: the remainder, net of discounts" chargebee.invoice -> suger.credit: "net below what was reported" chargebee.voided -> suger.credit: "credit back what was reported" suger.record -> marketplace: "reported usage" suger.credit -> marketplace: "spent first on later usage" { style.stroke-dash: 4 } ``` ### When something fails - **One buyer does not stop the run.** If Fours cannot report a buyer's usage, it logs the failure and moves on to the next buyer. A run in which every linked buyer fails is marked failed and retried once. - **A window Fours cannot place is skipped, not guessed.** A billing window whose currency differs from the entitlement's, or that no single entitlement covers, is skipped while the rest of the buyer's usage still reports. See [Which entitlement a window is billed to](#which-entitlement-a-window-is-billed-to). - **A missed hour catches up.** Each run compares Chargebee's current figure for a window with the running total Fours has already reported for it, so the next successful run reports everything a failed one would have. - **Running the sync twice does not bill twice.** A repeated or retried run does not report the same usage a second time. ## Create Integration (Org-Level) ### Prerequisites - **Chargebee Site Name**: The unique identifier for your Chargebee instance (found in your Chargebee URL). - **Full-Access API Key**: An API key generated from your Chargebee dashboard. Refer to the [Chargebee API Documentation](https://www.chargebee.com/docs/2.0/api_keys.html) for the specific generation steps. ### Authenticate 1. In the [Fours Console](https://console.suger.io/settings?tab=integrations), navigate to **Settings > Integrations**. 2. Locate the **Chargebee** card and click **Connect**. 3. Enter your connection details: - **Site Name**: Enter your Chargebee site identifier. - **API Key**: Paste the API key generated from your Chargebee dashboard. ![Chargebee integration setup dialog with Site Name and API Key fields](images/integrate-chargebee-with-suger-1.jpg) 4. Click **Create**. Fours verifies the connection and begins identifying your Chargebee resources. ## Edit Integration Editing requires the **Admin** role. Open the **⋯** menu on the Chargebee card under **Settings > Integrations** and click **Edit** to open **Edit Integration - Chargebee**. It holds the usage-sync settings: - **Enable Auto Report Usage**: When on, the hourly sync reports the metered overage Chargebee has priced to each linked buyer's marketplace bill. Turning it on sets **Billing Mode** to `amount` for you, and turning it off clears the mode, so the integration cannot be saved half configured. - **Billing Mode**: Shown while **Enable Auto Report Usage** is on. `amount` is the only mode — see [Billing Mode](#billing-mode). Click **Save** to apply the change. Credentials cannot be edited. To maintain a high security standard, Fours limits the modification of active credentials. If you need to rotate your API key or change your site name, delete the existing integration and reconnect using the new details — then turn **Enable Auto Report Usage** back on, because a new integration starts with it off. ## Delete Integration Click the 🗑️ icon on the Integrations page. This immediately and permanently removes all Chargebee credentials from Fours' secure vault. :::warning This does not affect your data in Chargebee. ::: ## Billing Mode Chargebee has one billing mode, **`amount`**: Fours reports the overage Chargebee has already priced, not raw usage quantities. Every amount is reported on the single source dimension key `chargebee`, where one unit is one unit of the entitlement's currency — `$1` on a USD entitlement. :::warning - The `chargebee` key has to land on a dimension the entitlement actually has. Either your product defines a dimension keyed or named `chargebee`, or you map `chargebee` to the dimension you bill the overage through in [Metering Dimension Conversion](/metering/usage-metering/#metering-dimension-conversion), for each cloud marketplace you sell through. A mapping multiplies each amount by its multiplier, so a dimension priced at $1 per unit takes a multiplier of 1. A record whose key matches no dimension on the entitlement is rejected, and that usage is not reported. - The Chargebee subscription's currency must match the entitlement's currency. A window in any other currency is skipped. ::: ## How Fours settles each billing window Chargebee shows a billing window's priced overage in two places at different times: a live **usage charge** while the window is open, then the **invoice** once it closes. Fours reads both, separately for each metered addon on each of the buyer's subscriptions: 1. **While the window is open**, each hourly run reads the usage charges of the customer's `active` and `non_renewing` subscriptions and reports only the growth since the previous read. 2. **When the window closes**, Fours settles it against its invoice — an invoice in `posted`, `payment_due`, `not_paid` or `paid` status, updated within the last two months. The metered line is taken **net of Chargebee discounts**, and whatever the hourly reads did not already cover is reported. A `pending` invoice is left until Chargebee closes it. 3. **If the net invoice line is lower than what Fours already reported** — typically because a coupon took money off — the difference cannot be pulled back from the marketplace. Fours adds it to the entitlement as [credit](/metering/usage-credit/) instead, which is spent first on the buyer's later usage. 4. **If an invoice is voided after Fours reported its window**, Fours credits the reported amount back to the entitlement that was billed. Fours timestamps each settlement inside the window it settles, so Fours' own period views line up with the Chargebee invoice. The marketplace still bills a record when Fours submits it, so reconcile a Chargebee invoice against Fours' records window by window rather than month by month. ### Which entitlement a window is billed to - **Exactly one entitlement must cover the window's start.** Fours bills a window to the buyer's active or pending-cancel entitlement whose term contains the moment the window opened. If none does — or more than one does, for example two of the buyer's entitlements running at the same time — Fours skips the window rather than guess. If that entitlement renews while the window is still being reported, the rest of the window moves to the entitlement in force at that time. - **A closed window Fours never reported live is skipped.** Fours settles a closed window only if it reported that window while it was open. Typical examples are windows that closed before you linked the buyer — whose invoice may already have been paid in Chargebee — and windows that closed while **Enable Auto Report Usage** was off. The first time Fours sees a window that is still open, it reports everything its usage charge already holds. - **Cancellation picks up the last window.** When an AWS or Google Cloud entitlement is being cancelled, Fours runs the sync once more for that buyer, so the final window's usage is reported. ## Connect Chargebee Customer To let Fours report a buyer's Chargebee usage to the right cloud marketplace entitlement, connect the Buyer in Fours with its customer in Chargebee. Find the buyer on the **Companies** page (see [Companies](/console/company/)) and click the **Edit** action on its row — or open its company page and choose **More actions** → **Edit info**. In the **Edit Buyer** panel, under **Integration Information**, enter the **Chargebee customer ID**. Every hourly run then picks that buyer up. Keep the ID current — if the buyer moves to a different Chargebee customer, update it here. Buyers without a Chargebee customer ID are never synced. --- Source: https://doc.fours.com/integrations/clickup/ # ClickUp ## Overview ClickUp integration allows you to manage ClickUp tasks and workflows directly from Fours. ### Org-Level vs User-Level > **User-Level Only**: ClickUp integration is configured per user. Each user authenticates with their own ClickUp account via OAuth. ## Create Integration 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to ClickUp to authorize 3. Grant access to your ClickUp workspace 4. Return to Fours to confirm connection ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the ClickUp API directly. > **User-level only**: ClickUp tools use each user's personal OAuth credentials. **Workspaces & Spaces** | Tool | Description | |------|-------------| | `clickup_list_workspaces` | List all workspaces (teams) the user belongs to | | `clickup_list_spaces` | List spaces in a workspace | | `clickup_list_folders` | List folders in a space | | `clickup_list_lists` | List lists in a space | | `clickup_list_folder_lists` | List lists inside a folder | **Tasks** | Tool | Description | |------|-------------| | `clickup_list_tasks` | List tasks in a list | | `clickup_list_team_tasks` | List tasks across a workspace with filters | | `clickup_get_task` | Get a task by ID | | `clickup_create_task` | Create a new task in a list | | `clickup_update_task` | Update task fields (name, status, assignees, etc.) | | `clickup_fetch_attachment` | Fetch a task attachment by URL | **Comments** | Tool | Description | |------|-------------| | `clickup_create_comment` | Add a comment to a task | | `clickup_get_comments` | Get all comments on a task | **User** | Tool | Description | |------|-------------| | `clickup_get_authorized_user` | Get the currently authenticated ClickUp user | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration. :::warning Deleting the integration will remove access to ClickUp immediately. ::: --- Source: https://doc.fours.com/integrations/cloudflare/ # Cloudflare Workers AI Connect your Cloudflare Workers AI API token and account ID to run Fours' AI features on Workers AI models. --- ## Overview Cloudflare Workers AI is an AI model provider (category: AI). When you connect your own Workers AI API token (bring-your-own-key), the Workers AI chat models Fours supports become available to Fours' AI features — for example, you can choose one as an agent's **Default model**. Cloudflare bills the model usage to your Cloudflare account; for how Fours meters AI requests that run on your own key, see [What is metered](/insulin/billing/metering/#using-your-own-provider-keys-byok). Fours offers a fixed set of Workers AI chat models, not Cloudflare's whole catalog: | Model | Workers AI model ID | | --- | --- | | Llama 3.3 70B Instruct (fast) | `@cf/meta/llama-3.3-70b-instruct-fp8-fast` | | Llama 3.1 8B Instruct (fp8) | `@cf/meta/llama-3.1-8b-instruct-fp8` | | GPT-OSS 120B | `@cf/openai/gpt-oss-120b` | | Qwen2.5 Coder 32B Instruct | `@cf/qwen/qwen2.5-coder-32b-instruct` | | Mistral Small 3.1 24B Instruct | `@cf/mistralai/mistral-small-3.1-24b-instruct` | ### Org-Level vs User-Level - **Org-Level**: one token shared by your organization. Organization agents draw on it. Only an organization **Admin** can connect or disconnect it. - **User-Level**: your own token. Your Personal agents draw on it; it never serves anyone else in your organization. --- ## Create Integration ### Prerequisites - A **Workers AI API token**. In the Cloudflare dashboard, go to **Workers AI**, select **Use REST API**, then **Create a Workers AI API Token** and **Create API Token**. If you build a custom token instead, it needs both the **Workers AI - Read** and **Workers AI - Edit** permissions — see Cloudflare's [REST API](https://developers.cloudflare.com/workers-ai/get-started/rest-api/) guide. A read-only token passes Fours' connect check but cannot run models. - Your Cloudflare **Account ID**, shown under **Get Account ID** on the same **Use REST API** page (or see Cloudflare's [Find account and zone IDs](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/)). Fours accepts it only as a 32-character hexadecimal value. ### Connect 1. Open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) in the Fours console. 2. Find the **Cloudflare Workers AI** card — in the **Integrations** grid to connect it for your organization, or under **User Integrations** to connect it for yourself — and click **Connect**. 3. In the **Connect Cloudflare Workers AI** dialog, click **Start connection**. 4. Enter your Workers AI API token and your Account ID — the organization form labels them **API Token** and **Account ID** — and click **Save credentials**. Before storing your credentials, Fours checks the Account ID's shape and then uses your token to list Workers AI models in that account: ```d2 direction: down save: "Save credentials\nAPI token + Account ID" shape_check: "Account ID is 32\nhexadecimal characters?" { shape: diamond } probe: "Fours asks Cloudflare for your\naccount's Workers AI model list,\nusing your token" answer: "Cloudflare's answer" { shape: diamond } connected: "Connected\ntoken and Account ID stored" fix_id: "Rejected: fix the Account ID\nnothing stored" fix_token: "Rejected: fix the token\nnothing stored" retry: "Not confirmed: try again later\nnothing stored" save -> shape_check shape_check -> fix_id: "no" shape_check -> probe: "yes" probe -> answer answer -> connected: "200 OK" answer -> fix_token: "401 / 403" answer -> retry: "anything else\n(timeout, 404, 429, 5xx)" ``` | What the form shows | What it means | | --- | --- | | `Invalid connection config field "accountId": must be a 32-character hexadecimal Cloudflare account id` | The Account ID is not 32 hexadecimal characters. Copy it again from Cloudflare. | | `Cloudflare Workers AI rejected the supplied API key` | Cloudflare refused the token. Check that you pasted the whole token and that it has not been revoked. | | `Cloudflare Workers AI could not confirm the key right now (status …)` or `Could not reach Cloudflare Workers AI to verify the key` | Fours got no usable answer — a timeout, a rate limit, an outage, or an account Cloudflare does not recognise. The token was **not** judged invalid; check the Account ID and try again. | :::info Once connected, the models in the table above appear in Fours' model pickers — for example an agent's **Default model** (see [Agents](/insulin/agents/)). If your organization limits AI providers under **Settings → Organization → AI Model Policy**, add **Cloudflare Workers AI** to its **Allowed AI integrations** list — otherwise requests on these models are refused, whichever key they would use. See [AI Model Policy](/insulin/getting-started/#ai-model-policy). ::: ## Edit Integration There is no **Edit** option. To replace the token or the Account ID — for example after rotating the token in Cloudflare — reconnect the integration: 1. Open the **⋯** menu on the Cloudflare Workers AI card and choose **Details**. 2. Click **Reconnect**, then **Start connection**, enter the new values, and click **Save credentials**. Fours checks the new values exactly as it does on first connect, and replaces the stored credential only when they pass — a rejected token leaves the previous one in place. For an organization connection, reconnecting also requires the **Admin** role. Fours checks the token only when you connect or reconnect, so reconnect whenever you revoke or replace it on the Cloudflare side. ## Delete Integration Open the **⋯** menu on the Cloudflare Workers AI card and choose **Disconnect**. This removes the connection from Fours, so its models can no longer run on that credential. An agent whose **Default model** is a Workers AI model then shows it as **unavailable** in its model picker, with a hint to reconnect the provider or choose another model. :::info Cloudflare Workers AI serves chat models only in Fours. Fours registers no Workers AI embedding model, so connecting it adds nothing to the knowledge-base embedding chooser — see [Choosing an embedding model](/insulin/knowledge-base/#choosing-an-embedding-model). ::: --- Source: https://doc.fours.com/integrations/databricks/ # Databricks Connect to Databricks to unify data, run analytics, and trigger workflows. --- ## Overview [Databricks](https://databricks.com) is a Data Intelligence Platform enables organizations to unify data, analytics, and AI workflows, allowing teams to build generative AI applications, democratize data insights, and govern enterprise data across multiple cloud environments while integrating with existing tools. Connecting Fours to your Databricks account enables you to automate tasks within Databricks and integrate it with other applications, allowing for actions such as executing SQL queries, uploading data files, and triggering to run jobs defined in Databricks. ## Create Integration 1. Set up a Databricks account. 2. Fours supports two kinds of Databricks authentication, following each documents to generate the corresponding credentials: - [Personal access token authentication](https://docs.databricks.com/aws/en/dev-tools/auth/pat) - [OAuth service principal authentication](https://docs.databricks.com/aws/en/dev-tools/auth/oauth-m2m) 3. Click the Databricks "Connect" button on the "Integrations" page. 4. Enter Connection Information: - Host: The Databricks host URL, e.g. `https://.cloud.databricks.com` - Choose the authentication method you generated in step 2. - For **Personal access token authentication**, enter: - Token: The personal access token you generated in step 2. - For **OAuth service principal authentication**, enter: - Client ID: The client ID you generated in step 2. - Client Secret: The client secret you generated in step 2. Example 1: Create integration using **Personal access token authentication**: > Databricks integration setup with personal access token authentication Example 2: Create integration using **OAuth service principal authentication**: > Databricks integration setup with OAuth service principal authentication ## Edit Integration Edit is not supported for Databricks integration. For security, if you need to update credentials, delete the integration and recreate it. ## Delete Integration To delete the integration, simply click the 🗑️ button in the "Integrations" list. We will remove any credentials in our system. --- Source: https://doc.fours.com/integrations/datadog/ # Datadog ## Overview Datadog is a monitoring and observability platform for infrastructure, application performance, logs, and security. Connect Datadog to Fours so the Fours AI agent can verify your Datadog account and manage Datadog users (provision and disable) as part of your operations workflows. ### Org-Level vs User-Level > **Org-Level**: Organization-wide Datadog access via an API key and application key. All users in the organization share the same Datadog connection. > > **User-Level**: Personal Datadog access per user via an API key and application key. Each user connects their own Datadog credentials. ## Create Integration (Org-Level) ### Prerequisites - Datadog account with API access - Datadog API key and Application Key ### Authenticate 1. Navigate to Settings > Integrations 2. Click "Connect Datadog" 3. Enter your Datadog API Key and Application Key 4. Select the Datadog site (US, EU, or other) 5. Click Verify to test the connection 6. Upon successful verification, the integration status is updated to `verified` :::note You can find your API key and Application Key in the [Datadog API settings](https://app.datadoghq.com/organization-settings/api-keys). ::: ## Create User Integration Use user-level integration when you want to connect your personal Datadog account. 1. Click `Connect Now` button in the User Integrations section 2. Enter your Datadog **API Key** and **Application Key** 3. Select your Datadog **site** (US1, US3, US5, EU1, or AP1) 4. Submit to confirm the connection :::note Datadog does not offer an OAuth app — both org-level and user-level connections use an API key plus application key, not a redirect flow. ::: ## Fours AI Tools When Datadog is connected, the Fours AI agent can manage Datadog through Fours' built-in tools. This is a focused integration with three actions. > **Org-level and user-level**: Both are supported; user-level takes precedence when both are connected. | Capability | What the agent can do | |------------|-----------------------| | **User management** | Provision and disable Datadog users (`create-user`, `disable-user`) | | **Account** | Verify the connected Datadog account and API-key validity (`get-account`) | ## Edit Integration Editing not supported. Delete and recreate. ## Delete Integration Deleting removes the integration and revokes the stored Datadog credentials from Fours. :::warning This does not delete any users, dashboards, or monitors in Datadog. Revoke the API key and application key in Datadog if they are no longer needed. ::: --- Source: https://doc.fours.com/integrations/deepinfra-byok/ # DeepInfra Connect your DeepInfra API key to run Fours' AI features on the models DeepInfra serves. --- ## Overview DeepInfra is an AI model provider (category: AI). By connecting your own DeepInfra API key (bring-your-own-key), the models DeepInfra offers become selectable in Fours' model picker — for Insulin agents, chat, inference, and knowledge-base embeddings. API usage is billed directly by DeepInfra to your account; Fours does not charge for these models. ### Org-Level vs User-Level - **Org-Level**: the key is shared across your organization. Its models are available to organization-level agents and to members of the org. Connecting requires an organization admin. - **User-Level**: the key is personal to your workspace. Its models are available to your own user-level agents and personal Insulin. --- ## Create Integration 1. Navigate to the [Fours Console Integrations](https://console.suger.io/settings?tab=integrations) page. 2. Find the **DeepInfra** integration and click **Connect**. 3. Choose the level — **Organization** (shared) or **User** (personal). 4. Paste your **DeepInfra API Key** and click **Save credentials**. Fours verifies the key with DeepInfra before storing it, so an invalid key is rejected at connect time rather than surfacing later as a failed model run. > Generate an API key in your DeepInfra account at [deepinfra.com](https://deepinfra.com/) (**API Keys**). :::info After connecting, open any model picker — an agent's **Default Model**, or **Insulin model settings** — and DeepInfra's models appear, with verified models grouped first and each entry attributed to DeepInfra. ::: ## Edit Integration Editing the API key is not supported. To change the key, delete the integration and create a new one. ## Delete Integration You can delete the DeepInfra integration at any time. This permanently removes the stored credential. Any agent pinned to a DeepInfra model then shows that model as **unavailable** with a reconnect prompt until you reconnect DeepInfra or pick another model — Fours never silently substitutes a different model. :::info DeepInfra also serves knowledge-base embeddings on your own key: **DeepInfra · BGE-M3** and **DeepInfra · Qwen3 Embedding 0.6B** appear in the embedding-model chooser once this integration is connected at the knowledge base's level — an organization connection for an organization knowledge base, your personal connection for a private one. Organization knowledge bases can also use the Fours-hosted models, which need no key — see [Knowledge Bases](../../insulin/knowledge-base/). ::: --- Source: https://doc.fours.com/integrations/digitalocean/ # DigitalOcean GradientAI Connect your DigitalOcean model access key to run Fours' AI features on GradientAI serverless-inference models. --- ## Overview DigitalOcean GradientAI is an AI model provider (category: AI). When you connect your own DigitalOcean model access key (bring-your-own-key), the GradientAI chat models Fours supports become available to Fours' AI features — for example, you can choose one as an agent's **Default model**. DigitalOcean bills the model usage to your DigitalOcean account; for how Fours meters AI requests that run on your own key, see [What is metered](/insulin/billing/metering/#using-your-own-provider-keys-byok). Fours offers a fixed set of GradientAI chat models, not DigitalOcean's whole catalog: | Model | DigitalOcean model ID | | --- | --- | | Llama 4 Maverick | `llama-4-maverick` | | GPT-OSS 120B | `openai-gpt-oss-120b` | | Claude Sonnet 5 | `anthropic-claude-5-sonnet` | | DeepSeek V4 Pro | `deepseek-v4-pro` | | Qwen 3.5 397B A17B | `qwen3.5-397b-a17b` | ### Org-Level vs User-Level - **Org-Level**: one key shared by your organization. Organization agents draw on it. Only an organization **Admin** can connect or disconnect it. - **User-Level**: your own key. Your Personal agents draw on it; it never serves anyone else in your organization. --- ## Create Integration ### Prerequisites - A DigitalOcean **model access key** for serverless inference. In the DigitalOcean control panel, open **INFERENCE → Manage** and click **Create model access key** — see DigitalOcean's [How to Create and Manage Model Access Keys](https://docs.digitalocean.com/products/inference/how-to/manage-model-access-keys/). The secret is shown only once, right after you create it. - When you create the key, give it access to the models you plan to use (**All models**, or **Select models** covering the ones in the table above). Do not restrict it to a VPC network: DigitalOcean then accepts only requests that come from inside that network, and Fours' requests do not. ### Connect 1. Open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) in the Fours console. 2. Find the **DigitalOcean GradientAI** card — in the **Integrations** grid to connect it for your organization, or under **User Integrations** to connect it for yourself — and click **Connect**. 3. In the **Connect DigitalOcean GradientAI** dialog, click **Start connection**. 4. Paste your model access key — the organization form labels it **Model Access Key** — and click **Save credentials**. Before storing the key, Fours uses it to request the model list from DigitalOcean's serverless-inference endpoint. That proves DigitalOcean accepts the key; it does not check which models the key may use, so scope it as described above: ```d2 direction: down save: "Save credentials\nmodel access key" probe: "Fours requests DigitalOcean's\nmodel list, using your key" answer: "DigitalOcean's answer" { shape: diamond } connected: "Connected\nkey stored" fix_key: "Rejected: fix the key\nnothing stored" retry: "Not confirmed: try again later\nnothing stored" save -> probe -> answer answer -> connected: "200 OK" answer -> fix_key: "401 / 403" answer -> retry: "anything else\n(timeout, 404, 429, 5xx)" ``` | What the form shows | What it means | | --- | --- | | `DigitalOcean GradientAI rejected the supplied API key` | DigitalOcean refused the key. Check that you pasted the whole secret and that the key has not been deleted or regenerated. | | `DigitalOcean GradientAI could not confirm the key right now (status …)` or `Could not reach DigitalOcean GradientAI to verify the key` | Fours got no usable answer — a timeout, a rate limit, or an outage. The key was **not** judged invalid; try again. | :::info Once connected, the models in the table above appear in Fours' model pickers — for example an agent's **Default model** (see [Agents](/insulin/agents/)). If your organization limits AI providers under **Settings → Organization → AI Model Policy**, add **DigitalOcean GradientAI** to its **Allowed AI integrations** list — otherwise requests on these models are refused, whichever key they would use. See [AI Model Policy](/insulin/getting-started/#ai-model-policy). ::: ## Edit Integration There is no **Edit** option. To replace the key — for example after regenerating it in DigitalOcean — reconnect the integration: 1. Open the **⋯** menu on the DigitalOcean GradientAI card and choose **Details**. 2. Click **Reconnect**, then **Start connection**, paste the new key, and click **Save credentials**. Fours checks the new key exactly as it does on first connect, and replaces the stored credential only when it passes — a rejected key leaves the previous one in place. For an organization connection, reconnecting also requires the **Admin** role. Fours checks the key only when you connect or reconnect, so reconnect whenever you delete or regenerate it on the DigitalOcean side. ## Delete Integration Open the **⋯** menu on the DigitalOcean GradientAI card and choose **Disconnect**. This removes the connection from Fours, so its models can no longer run on that credential. An agent whose **Default model** is a GradientAI model then shows it as **unavailable** in its model picker, with a hint to reconnect the provider or choose another model. :::info DigitalOcean GradientAI serves chat models only in Fours. Fours registers no GradientAI embedding model, so connecting it adds nothing to the knowledge-base embedding chooser — see [Choosing an embedding model](/insulin/knowledge-base/#choosing-an-embedding-model). ::: --- Source: https://doc.fours.com/integrations/dns-email/ # DNS Email ## Overview The **DNS Email** integration lets your organization send workflow and notification emails from **your own verified domain** (for example `noreply@notifications.acme.com`) instead of the default Fours sender (`noreply@suger.io`). Delivery is powered by AWS Simple Email Service (SES) with a DKIM-verified domain identity. Use this integration when you want: - **Branded sender addresses** — recipients see your domain, not Fours'. - **Reputation isolation** — outbound mail from your workflows is scoped to a subdomain you control. - **Deliverability hardening** — DKIM signatures, a custom MAIL FROM domain (proper SPF alignment), and a DMARC policy are configured for you automatically. Once verified, the integration is consumable by the **DNS Email** workflow node, so any workflow you build can send mail from your domain. :::tip[Why a subdomain?] We strongly recommend a dedicated subdomain (for example `notifications.acme.com`, `updates.acme.com`, or `billing.acme.com`) rather than your root domain. A subdomain isolates Fours' sending reputation from the rest of your company's mail and is easier to delegate DNS changes for. ::: ### Org-Level vs User-Level > **Org-Level**: The DNS Email integration is **org-level only**. All workflows in the organization share a single verified domain identity. > > **User-Level**: Not supported. There is no per-user variant of this integration. ## Prerequisites Before creating the integration, make sure you have: - A domain (or subdomain) you control — for example `notifications.acme.com`. - Access to the DNS zone for that domain so you can add 7 records (3 CNAME + 1 MX + 3 TXT). - Admin rights in your Fours organization to create integrations. Domain rules enforced at creation: - Must be a valid domain name (`example.com`, `mail.example.com`, …). - Internationalized Domain Names (IDN / `xn--` punycode) are **rejected**. - IP addresses are **rejected**. - The value is normalized to lowercase. - **Bare public suffixes are rejected.** You cannot claim `com`, `co.uk`, or any other registry suffix on its own — the domain must be one you can actually register and control. - **Reserved domains are rejected.** Fours' own sending domain, `suger.io`, `suger.cloud`, and `amazonses.com` cannot be claimed, and neither can any subdomain of them. ### One organization per domain A domain can be claimed by **only one Fours organization**. If you try to create a DNS Email integration for a domain another organization already holds, creation fails with: ``` domain is already claimed by another organization ``` The check is **case-insensitive** — `Notifications.Acme.com` and `notifications.acme.com` are the same claim. :::note For privacy, the error does **not** tell you which organization holds the existing claim. If you believe the domain is yours and the claim is stale — for example it was created under a Fours organization your company no longer uses — the holding organization must delete its integration before you can create yours, or you can contact Fours support. Claiming a **different subdomain** (`updates.acme.com` instead of `notifications.acme.com`) is unaffected and is usually the fastest way forward. ::: ## Create Integration (Org-Level) 1. Navigate to **Settings → Integrations** in the Fours console. 2. Click **Connect** on the **DNS Email** card. 3. Fill in the form: - **Domain** *(required)* — the custom (sub)domain you want to send from, e.g. `notifications.acme.com`. - **From Email** *(optional)* — the default sender address used by workflows that don't override it, e.g. `noreply@notifications.acme.com`. If left empty, Fours will use `noreply@`. The domain portion **must match** the integration domain. 4. Click **Create**. When you submit, Fours calls AWS SES on your behalf and: 1. Generates a one-off **verification nonce** for your domain and derives a domain-ownership TXT record from it. 2. Registers your domain as a SES sending identity and obtains 3 DKIM tokens. 3. Configures a custom MAIL FROM subdomain (`mail.` by default) for proper SPF alignment and bounce handling. 4. Returns the 7 DNS records you need to add to your DNS provider. The integration is created in `CREATED` status. It moves to `VERIFIED` only after the DNS records propagate and you click **Verify** (see below). ### Configure DNS Records After creation, the integration detail page shows 7 records across 4 categories. **Not all of them gate the same thing** — the table below shows exactly what each one is for and what happens if you skip it. Assume your integration domain is `notifications.acme.com`; values below use realistic placeholders. #### Requirement Summary | # | Record | Status | Required for `VERIFIED` status? | Required for actual delivery? | Why | |---|--------|--------|---------------------------------|-------------------------------|-----| | 1 | Fours ownership TXT (×1) | **Required** | ✅ Yes | ✅ Yes (via `VERIFIED`) | Proves to **Fours** that you control the domain, independently of SES. Fours looks up this TXT record itself and compares it to the nonce it stored at creation. Without an exact match the integration never reaches `VERIFIED`, so the workflow node refuses to send. | | 2–4 | DKIM CNAMEs (×3) | **Required** | ✅ Yes | ✅ Yes | Proves domain ownership to SES *and* attaches a DKIM signature to every outbound email. SES blocks the identity from sending until all three are detected. | | 5 | MAIL FROM MX (×1) | **Required** | ✅ Yes | ✅ Yes | SES checks this MX record to mark the custom MAIL FROM subdomain as `Success`. Without it the integration cannot reach `VERIFIED` and the workflow node refuses to send. | | 6 | MAIL FROM SPF TXT (×1) | **Required for deliverability** | ❌ No | ✅ Yes (effectively) | Not part of SES's verification gate, so the integration *can* technically reach `VERIFIED` without it — but downstream receivers (Gmail, Outlook, corporate filters) will fail SPF on the custom MAIL FROM domain and quarantine or reject your mail. Skip it and you have a "verified-but-undeliverable" integration. | | 7 | DMARC TXT (×1) | **Recommended** | ❌ No | ⚠️ Strongly recommended | Not checked by SES or by Fours. Provides a published policy + reporting address so receivers know how to treat unauthenticated mail from your domain. Modern providers (notably Gmail/Yahoo for bulk senders) increasingly require a valid DMARC record; without it, deliverability degrades over time. | > **TL;DR**: Records 1–5 are **must-add** (without them, **Verify** never succeeds). Record 6 is **must-add for any real-world use** (without it, recipients reject your mail even though Fours says "verified"). Record 7 is **strongly recommended** and trivially cheap to add. #### 1. Domain ownership verification (1 × TXT) — **Required** Proves to Fours that the domain is yours. This is Fours' own check, separate from anything SES does: at creation Fours generates a random nonce for your integration, and at verification time it looks up this TXT record and requires an **exact** match. | Type | Name | Value | |------|-------------------------------------|---------------------------------------------| | TXT | `_suger-verify.notifications.acme.com` | `suger-domain-verification=` | This is the **first** section shown in the records dialog, under the heading **Domain ownership verification**. :::note The `` is unique to your integration and is shown in the console after creation — copy it verbatim. It is generated by Fours; a nonce you supply yourself is discarded. Because it is regenerated for a new integration, if you delete and recreate the integration you must **replace** this TXT record with the new value; the old one will not verify. ::: > **Why this exists in addition to DKIM:** the DKIM CNAMEs prove control to *Amazon SES*. This record proves control to *Fours*, which is what stops one organization from claiming a domain it does not own inside Fours. Both checks must pass. #### 2. DKIM (3 × CNAME) — **Required** Proves domain ownership to SES (modern replacement for the legacy TXT verification token) and DKIM-signs every outbound email. | Type | Name | Value | |-------|-------------------------------------------------------|----------------------------------------------------| | CNAME | `._domainkey.notifications.acme.com` | `.dkim.amazonses.com` | | CNAME | `._domainkey.notifications.acme.com` | `.dkim.amazonses.com` | | CNAME | `._domainkey.notifications.acme.com` | `.dkim.amazonses.com` | > **Why all three?** SES rotates DKIM keys. All three CNAMEs must resolve at any given time, or signing fails for some outbound messages. #### 3. MAIL FROM MX (1 × MX) — **Required** Routes bounce / complaint feedback for your custom MAIL FROM subdomain (`mail.`) back to SES. SES's MAIL FROM verification gate (`CustomMailFromStatus=Success`) is satisfied by the presence of this record. | Type | Name | Value | |------|-----------------------------------|--------------------------------------------------| | MX | `mail.notifications.acme.com` | `10 feedback-smtp.us-west-2.amazonses.com` | > The region in the value (`us-west-2`) matches the SES region Fours uses. **Do not change it.** #### 4. MAIL FROM SPF (1 × TXT) — **Required for deliverability** Publishes an SPF record on the MAIL FROM subdomain authorising Amazon SES to send on its behalf. Receivers use this to validate SPF alignment under DMARC. | Type | Name | Value | |------|-----------------------------------|--------------------------------------------------| | TXT | `mail.notifications.acme.com` | `v=spf1 include:amazonses.com ~all` | > **This is the most commonly skipped record** because Fours' `VERIFIED` status doesn't depend on it. Skip it and your mail will pass SES's gate but fail at Gmail/Outlook with `spf=softfail` or `spf=fail`. Add it. #### 5. DMARC (1 × TXT) — **Recommended** Tells receivers what to do with mail that fails DKIM or SPF on your domain, and (optionally) where to send aggregate reports. Not enforced by SES or by Fours, but essential modern hygiene — and increasingly required for bulk senders by Gmail and Yahoo. | Type | Name | Value | |------|---------------------------------------|-----------------------------| | TXT | `_dmarc.notifications.acme.com` | `v=DMARC1; p=quarantine;` | > The default policy is `p=quarantine;`. You may relax it (`p=none;` for monitor-only) or tighten it (`p=reject;`) once you're confident your alignment is correct. Adding `rua=mailto:dmarc-reports@yourcompany.com` lets you receive daily aggregate reports. :::note The exact `token1/token2/token3` values are unique to your integration and are shown in the console after creation. Copy them verbatim from the Fours UI. ::: #### Strip the zone suffix on providers that auto-append it Fours shows record names as **fully-qualified domain names** (FQDN), e.g. `_dmarc.notifications.acme.com`. That is the canonical form — and it is what a few providers (notably AWS Route 53) want verbatim. **However, many popular DNS hosts silently append the parent zone to whatever you type in the `Name` field.** Pasting the FQDN into them produces a doubled, broken record. Providers known to auto-append the zone (you MUST strip the suffix): - **Squarespace Domains** (formerly Google Domains) - **Cloudflare** - **GoDaddy** - **Namecheap** - **Hover** - **Porkbun** - **DNSimple** - **DigitalOcean DNS** - Most cPanel-based hosts (Bluehost, HostGator, SiteGround…) Providers that take the FQDN verbatim (do NOT strip): - **AWS Route 53** - **NS1** - Cloudflare when driven via API / Terraform with a trailing-dot FQDN (the UI still auto-appends) **How to strip:** chop `.` off the end of every `Name` field. The root of the zone itself is usually entered as `@` (or left blank). Worked example for integration domain `notifications.acme.com`, with DKIM tokens shortened to `abc1` / `abc2` / `abc3`: | What Fours shows (FQDN) | What to enter on Squarespace / Cloudflare / GoDaddy / … | |------------------------------------------------------|---------------------------------------------------------| | `_suger-verify.notifications.acme.com` | `_suger-verify` | | `abc1._domainkey.notifications.acme.com` | `abc1._domainkey` | | `abc2._domainkey.notifications.acme.com` | `abc2._domainkey` | | `abc3._domainkey.notifications.acme.com` | `abc3._domainkey` | | `mail.notifications.acme.com` *(MX)* | `mail` | | `mail.notifications.acme.com` *(SPF TXT)* | `mail` | | `_dmarc.notifications.acme.com` | `_dmarc` | :::danger[Double-suffix is the #1 reason `Verify` fails] If you paste `abc1._domainkey.notifications.acme.com` into a zone-appending provider, the record that actually gets published is `abc1._domainkey.notifications.acme.com.notifications.acme.com` — which SES will never find. Symptoms: - **Verify** keeps reporting DKIM pending well past the propagation window. - `dig CNAME abc1._domainkey.notifications.acme.com +short` from your laptop returns nothing (NXDOMAIN). - Looking up the doubled name (`abc1._domainkey.notifications.acme.com.notifications.acme.com`) *does* return the expected value — the smoking gun. **Fix:** edit each broken record in your provider's UI and remove the trailing `.notifications.acme.com` from the `Name` field. DNS re-propagates within minutes once the TTL expires; click **Verify** again. ::: **Special case — verifying the zone apex (e.g. `acme.com` itself):** if your integration domain *is* the zone apex, FQDN-stripping leaves an empty string. Most providers represent the apex as `@`. So `acme.com` → `@`, `_dmarc.acme.com` → `_dmarc`, `_suger-verify.acme.com` → `_suger-verify`, `mail.acme.com` → `mail`. Using a subdomain avoids this edge case entirely — another reason to prefer one. #### Other common DNS-provider gotchas :::caution - **TXT quoting.** Some DNS UIs wrap TXT values in extra quotes. The published value must be the bare string (e.g. `v=spf1 include:amazonses.com ~all`) — not `"v=spf1 include:amazonses.com ~all"`. Cloudflare's UI strips one layer of quotes; Squarespace and GoDaddy do not. - **Conflicting existing records.** If `mail.` already has an MX (from a previous experiment or another vendor), the new SES MX may conflict or be ignored. Remove the old one first. - **MX priority field.** When the provider asks for the MX `Priority` and `Value` separately, enter `10` in Priority and `feedback-smtp.us-west-2.amazonses.com` in Value — not the combined string `10 feedback-smtp.us-west-2.amazonses.com`. - **CNAME at apex.** A few providers reject CNAMEs at the zone apex. DKIM CNAMEs live at `._domainkey.`, not at the apex, so this generally isn't an issue — but it bites you if you try to verify the apex itself with a CNAME-flattening trick. - **Slow TTLs.** Default TTLs of 24h–72h delay verification. Drop the TTL on these 7 records to 300s while you're setting up; raise it later if you prefer. - **The ownership TXT must match exactly.** Fours compares the published value byte-for-byte against the nonce it stored. A truncated paste, a stray space, a wrapping quote, or a leftover value from a previous integration all read as "not verified" rather than as a partial match. To sanity-check your records before clicking **Verify**, run: ```bash dig TXT _suger-verify.notifications.acme.com +short dig CNAME ._domainkey.notifications.acme.com +short dig MX mail.notifications.acme.com +short dig TXT mail.notifications.acme.com +short dig TXT _dmarc.notifications.acme.com +short ``` Each should return exactly the value Fours showed you — no doubled suffix, no extra quotes, no missing pieces. ::: ### Verify DNS propagation typically takes a few minutes but can take up to 72 hours depending on your provider's TTLs. 1. On the integration detail page, click **Verify**. 2. Fours looks up the TXT record at `_suger-verify.` and checks it matches the verification nonce stored for your integration. 3. Fours queries AWS SES for the current DKIM status and the MAIL FROM domain status. 4. The integration moves to `VERIFIED` **only when all three** pass — domain ownership, DKIM, and MAIL FROM. If any is still pending, the integration stays in its current status and you can click **Verify** again later. Common reasons verification stays pending: - DNS records haven't propagated yet → wait, then re-verify. - **The ownership TXT is missing, mistyped, or stale.** Confirm `dig TXT _suger-verify. +short` returns exactly `suger-domain-verification=` with the nonce currently shown in the console. If you recreated the integration, the nonce changed and the old record no longer matches. - **Double-suffix** — you pasted the FQDN (e.g. `mail.notifications.acme.com`) into a provider that auto-appends the zone (Squarespace, Cloudflare, GoDaddy, …), producing `mail.notifications.acme.com.notifications.acme.com`. See [Strip the zone suffix](#strip-the-zone-suffix-on-providers-that-auto-append-it) above. - The CNAME or TXT value was wrapped in quotes by the DNS UI. - A conflicting existing record (e.g. an older MX on `mail.`) is shadowing the new one. - Records exist but TTL hasn't expired yet — propagation can be capped by your old TTL, not the new one. ### Test Once the integration is `VERIFIED`, use the **Test** action to send a real end-to-end email: 1. On the integration detail page, click **Test**. 2. Enter a recipient address. 3. Fours sends a one-shot test email from your configured `FromEmail` (or `noreply@` if you didn't set one) to that recipient. 4. The response includes the SES `MessageId`. Check the recipient's inbox (and spam folder) to confirm delivery and sender headers. :::caution **Test sends a real email.** It is gated on `VERIFIED` status and uses your AWS SES domain identity — it will count against your SES sending quota. ::: ## Use in Workflows After verification, the **DNS Email** node becomes a usable sender in the workflow editor. ### DNS Email Node | Property | Required | Description | |-----------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | To Email | yes | Recipient address. Must be a valid email. | | CC Email List | no | Additional recipients. Accepts comma-joined strings; whitespace and duplicates are stripped automatically. | | BCC Email List | no | Same rules as CC. | | From Email | no | Override the default sender for this node only. **The domain portion MUST match the verified integration domain** (case-insensitive). Both bare (`alerts@notifications.acme.com`) and angle-bracket (`"Acme Alerts" `) forms are accepted. | | Subject | yes | Subject line. | | Email Format | yes | `text`, `html`, or `both`. Determines which body fields are required. | | Text | cond. | Plain-text body. Required when format is `text` or `both`. | | HTML | cond. | HTML body. Required when format is `html` or `both`. | ### Sender (From) Resolution For each item the node processes, the effective From address is resolved in this order: 1. The node's **From Email** field (if non-empty) — validated against the integration domain. 2. The integration's **From Email** (if non-empty) — set when the integration was created. 3. `noreply@` — implicit fallback so a send always has a sender. This means an org admin can configure a sensible default once on the integration and individual workflows can override it on a per-node basis when needed. :::caution[Security gate] A workflow author **cannot** send mail "as" a domain the organization hasn't verified. If you put `alerts@evil.com` in the node's From Email field while the integration is verified for `notifications.acme.com`, the node fails with `fromEmail domain "evil.com" must match the verified integration domain "notifications.acme.com"`. This is enforced server-side, before any SES call is made. ::: ### Status Gate The DNS Email node refuses to send if the integration is not `VERIFIED`. If you see workflow runs failing with `DNS email integration is not verified (status=...)`, finish DNS setup and re-run **Verify** in the console. ### Multi-Item Sends The node executes once per input item from the upstream node. If the upstream produces 10 records, the node makes 10 SES `SendEmail` calls — one email per item — and emits one result entry per send. ## Edit Integration > Editing is **not supported** for security and DNS-consistency reasons. To change the domain or the default From address, delete the integration and create a new one with the new values. (You will need to re-add the DNS records for the new domain.) ## Delete Integration Deleting the integration in Fours: 1. Removes the SES domain identity in AWS — your verified domain is unregistered. 2. Removes the integration record and its `FromEmail` / `MailFromDomain` / DNS-record metadata from Fours. 3. Releases the domain claim, so the domain becomes available for another organization to claim. 4. Causes any workflow that references the **DNS Email** node to start failing on subsequent runs until a new integration is created or the node is removed. Deletion is **scoped to the organization that owns the sending domain**. You can only delete a sending domain your own organization claimed — a delete request from any other organization does not touch it, even if that organization knows the domain name. This is the same ownership boundary that makes the claim exclusive in the first place. :::warning - Deletion is **immediate and permanent** in Fours and in AWS SES. There is no undo and no recovery window. - Fours does **not** clean up the DNS records you added to your zone. You are free to leave them, but if you do not plan to recreate the integration we recommend removing the ownership TXT record at `_suger-verify.`, the DKIM CNAMEs, the MAIL FROM MX/TXT records, and the DMARC TXT record at `_dmarc.` to keep your DNS zone tidy. - Any in-flight workflow executions that were about to call the DNS Email node will fail because the integration is gone. ::: ## FAQ **Which AWS region is used?** SES domain identities are created in **`us-west-2`**. This is reflected in the MX value for the custom MAIL FROM record (`feedback-smtp.us-west-2.amazonses.com`). **Do I have to use a subdomain?** No, you can verify a root domain (`acme.com`). We strongly recommend a subdomain to isolate sending reputation and avoid conflicts with existing MX/SPF/DKIM records on your primary mail domain. **Can two of our Fours organizations send from the same domain?** No. A domain is claimed by exactly one organization, and a second claim fails with `domain is already claimed by another organization`. Give each organization its own subdomain (`notifications.acme.com`, `eu-notifications.acme.com`) — they are distinct domains and can be claimed independently. **Why did verification stop working after I recreated the integration?** The domain-ownership nonce is generated fresh for each integration. The `_suger-verify.` TXT record still holds the previous integration's value, which no longer matches. Replace it with the new value shown in the console and click **Verify** again. **Can I configure a different MAIL FROM subdomain?** The default `mail.` is set automatically at creation. There is currently no UI to override it — recreate the integration if you need a different value. **Can each workflow use a different sender?** Yes — set the node's **From Email** field. The domain must match the integration domain, but the local-part (and display name) is free. Example: `alerts@notifications.acme.com`, `billing@notifications.acme.com`, `"Acme Updates" `. **Does this support attachments / reply-to / display name?** The current DNS Email node supports `to`, `cc`, `bcc`, `from` (with display name via angle brackets), `subject`, and text/HTML bodies. Per-send attachments and a dedicated reply-to field are not yet exposed on this node. **What happens to outbound mail if the integration becomes unverified?** SES periodically re-checks DKIM and MAIL FROM. If the records are removed from your DNS zone, SES will revoke the identity and Fours workflow runs will start failing the status gate (`DNS email integration is not verified`). Restore the records and click **Verify** to recover. --- Source: https://doc.fours.com/integrations/docusign/ # DocuSign ## Overview DocuSign is an electronic signature and agreement cloud platform that enables secure document signing and workflow automation. By connecting Fours to DocuSign, you can automate agreement signing processes, manage contracts, and track signature statuses for your cloud marketplace operations. ### Org-Level vs User-Level > **Org-Level**: Uses API key or OAuth for organization-wide access. > > **User-Level**: DocuSign integration is org-level only and does not support user-level connections. ## Create Integration (Org-Level) ### Prerequisites - DocuSign account with API access - DocuSign Integration Key (Client ID) and User ID - RSA keypair for JWT authentication or authorization code grant ### Authenticate 1. Navigate to Settings > Integrations 2. Click "Connect DocuSign" 3. Enter your DocuSign Integration Key and User ID 4. Configure authentication method (JWT or Authorization Code) 5. Click Verify to test the connection 6. Upon successful verification, the integration status is updated to `verified` :::note You can find your DocuSign Integration Key and User ID in the [DocuSign Developer Console](https://developers.docusign.com/). For production use, ensure you have the appropriate DocuSign plan with API access. ::: ## Edit Integration Editing not supported. Delete and recreate. ## Delete Integration Deleting removes the integration and stops all DocuSign envelope synchronization. :::warning Check DocuSign documentation for cleanup steps regarding any envelopes or templates that were created by Fours. ::: --- Source: https://doc.fours.com/integrations/dropbox/ # Dropbox ## Overview Dropbox is a cloud storage and file sharing platform for individuals and teams. Integrate with Dropbox to enable file access, sharing, and document management within Fours. ### Org-Level vs User-Level > **Org-Level**: Uses OAuth to connect your organization's Dropbox Business account. Provides access to team files and member data. > > **User-Level**: Uses OAuth to connect your personal Dropbox account. Provides access to your individual files and folders. ## Create Integration (Org-Level) ### Prerequisites - Dropbox Business account with admin access - Permission to authorize third-party apps ### Authenticate by OAuth 1. Navigate to Settings > Integrations 2. Click **Connect Dropbox** 3. You will be redirected to Dropbox to authorize 4. Log in and grant Fours access to your organization's Dropbox 5. Return to Fours — the integration status will show **Created** 6. Click **Verify** to confirm the connection The org-level integration requires the following Dropbox scopes: - `files.metadata.read`, `files.content.read`, `files.content.write` - `sharing.write`, `account_info.read` - `team_data.member`, `team_info.read` :::note The org (team) connection is focused on **browsing and downloading** files within team folders and exposes a smaller, read-oriented set of tools. Writes, sharing, batch operations, and file search are available on the **user-level** connection. ::: ## Create User Integration 1. Click **Connect Now** in the User Integrations section 2. You will be redirected to Dropbox to authorize 3. Grant Fours access to your personal Dropbox files 4. Return to Fours to confirm the connection 5. Click **Verify** to confirm ## Fours AI Tools When Dropbox is connected, the Fours AI agent can work with your files through Fours' built-in tools. The **user** connection exposes the full set (33 actions); the **org (team)** connection is a smaller, read-oriented subset for browsing and downloading within team folders. > **Org-level and user-level**: Both are supported; user-level takes precedence when both are connected. | Capability | What the agent can do | Level | |------------|-----------------------|-------| | **File & folder operations** | Upload, download, copy, move, delete, and read metadata (e.g. `upload-file`, `download-file`, `move-file-or-folder`) | User (download & metadata also on org) | | **Batch operations** | Bulk copy, move, delete, and create with async status polling (e.g. `batch-copy-files-or-folders`, `check-batch-move-files-or-folders`) | User | | **Sharing** | Manage shared links and shared folders (e.g. `create-shared-link`, `share-folder`) | User | | **Browse, search & revisions** | List folders, search, and manage revisions and temporary/zip links (e.g. `list-folder`, `search-files-and-folders`, `list-file-revisions`) | User (list & download on org) | | **Team folders** | List team folders on the Dropbox Business account (e.g. `list-team-folders`) | Org | | **Account & team admin** | Read the connected account and provision team users on Business (e.g. `get-account`, `create-user`, `delete-user`) | User / Org | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration and revokes stored credentials from Fours. :::warning To fully revoke access, also disconnect Fours from your Dropbox account settings at [dropbox.com/account/connected_apps](https://www.dropbox.com/account/connected_apps). ::: --- Source: https://doc.fours.com/integrations/fireworks/ # Fireworks AI Connect your Fireworks AI API key to run Fours' AI features on the models Fireworks serves. --- ## Overview Fireworks AI is an AI model provider (category: AI). By connecting your own Fireworks AI API key (bring-your-own-key), the models Fireworks offers become selectable in Fours' model picker — for Insulin agents, chat, inference, and knowledge-base embeddings. API usage is billed directly by Fireworks to your account; Fours does not charge for these models. ### Org-Level vs User-Level - **Org-Level**: the key is shared across your organization. Its models are available to organization-level agents and to members of the org. Connecting requires an organization admin. - **User-Level**: the key is personal to your workspace. Its models are available to your own user-level agents and personal Insulin. --- ## Create Integration 1. Navigate to the [Fours Console Integrations](https://console.suger.io/settings?tab=integrations) page. 2. Find the **Fireworks AI** integration and click **Connect**. 3. Choose the level — **Organization** (shared) or **User** (personal). 4. Paste your **Fireworks AI API Key** and click **Save credentials**. Fours verifies the key with Fireworks before storing it, so an invalid key is rejected at connect time rather than surfacing later as a failed model run. > Generate an API key in your Fireworks AI account at [fireworks.ai](https://fireworks.ai/) (**API Keys**). :::info After connecting, open any model picker — an agent's **Default Model**, or **Insulin model settings** — and Fireworks AI's models appear, with verified models grouped first and each entry attributed to Fireworks AI. ::: ## Edit Integration Editing the API key is not supported. To change the key, delete the integration and create a new one. ## Delete Integration You can delete the Fireworks AI integration at any time. This permanently removes the stored credential. Any agent pinned to a Fireworks AI model then shows that model as **unavailable** with a reconnect prompt until you reconnect Fireworks AI or pick another model — Fours never silently substitutes a different model. :::info Fireworks AI also serves knowledge-base embeddings on your own key: **Fireworks · Nomic Embed v1.5** appears in the embedding-model chooser once this integration is connected at the knowledge base's level — an organization connection for an organization knowledge base, your personal connection for a private one. Organization knowledge bases can also use the Fours-hosted models, which need no key — see [Knowledge Bases](../../insulin/knowledge-base/). ::: --- Source: https://doc.fours.com/integrations/gcp-cosell/ # GCP Co-Sell Connect Fours to Google Cloud Co-Sell to sync co-selling opportunities and referrals with Google through the **Google Cloud Partner Network** program (formerly Google Cloud Partner Advantage). :::info **Program name**: Google's partner program is **Google Cloud Partner Network**, launched in Q1 2026 with a six-month transition window for partners, and its portal is the **Partner Network Hub** at [partners.cloud.google.com](https://partners.cloud.google.com). The earlier **Partner Advantage** name is still visible in places — parts of the Google portal UI, Fours' integration card (**GCP Partner Advantage**), its **GCP Partner Advantage ID** field, and the API field `partnerAdvantageID`. They all refer to the same Google Cloud partner account. Program terminology verified against Google's documentation on 2026-08-05. ::: --- ## Overview The GCP Co-Sell program enables ISVs and partners to sell jointly with Google Cloud sales teams through the **Google Cloud Partner Network**, managed in the **Partner Network Hub**. With this integration, opportunities and referrals sync bidirectionally between Fours and the Partner Network Hub. :::info **Org-Level Only**: This is an organization-wide co-sell integration. User-level connections are not supported, which keeps data consistent across your entire sales team rather than tied to a single user's account. ::: ## Create Integration ### Prerequisites - An active [Google Cloud Partner Network](https://partners.cloud.google.com/enrollment) membership — the program formerly called Partner Advantage - Your company enrolled in the **GCP Co-Sell program** - **Admin** permissions in the [Partner Network Hub](https://partners.cloud.google.com/users) to authorize the integration ### Step 1 — Grant Fours access to your Partner Network Hub Add Fours' Google Service Account as an **Integrator** so Fours can read and submit co-sell opportunities on your behalf. 1. Log in to the [Partner Network Hub](https://partners.cloud.google.com/users) and navigate to the **Users** section. 2. Click **Assign roles**. 3. For **User email address**, enter Fours' Google Service Account email — contact support@suger.io to obtain it. 4. Select the **Integrator** role. 5. Click **Save**. ![Add Fours' Google Service Account as an Integrator](images/gcp-cosell-add-integrator.jpeg) The screenshot above predates the rename — its helper text still reads "Manage Partner Advantage users and their roles." You may still see the former name on some Google portal screens. ### Step 2 — Find your Partner ID 1. Go to the **Account** section of the [Partner Network Hub](https://partners.cloud.google.com/account). 2. Locate and copy your **Partner ID** under **Account information**. You will need this to finalize the connection in Fours. ![Where to find your GCP Partner ID](images/gcp-cosell-partner-id.jpeg) ### Step 3 — Connect in Fours 1. Log in to the Fours Console and go to [Settings > Integrations](https://console.suger.io/settings?tab=integrations). 2. Find the **GCP Partner Advantage** card and click **Connect Now**. (Fours' card still uses Google's former program name — see the note above.) 3. Paste the **Partner ID** you retrieved in Step 2 into the **GCP Partner Advantage ID** field. ![Enter your GCP Partner Advantage ID in Fours](images/integrate-gcp-partner-advantage-with-sug-4.png) 4. Click **Create**. 5. After creation succeeds, click **Verify** to confirm the connection is live and healthy. Sync behaviour is configured after the integration exists — see [Edit Integration](#edit-integration) below for the auto-delete toggle, and [Co-Sell Configuration](/cosell/cosell-configuration/) for field mapping. ## Edit Integration You can change the integration in place. You need the **ADMIN** role. 1. On the **GCP Partner Advantage** card, open the actions menu and choose **Edit**. 2. Update the **GCP Partner Advantage ID**, or toggle **Auto-Delete Rejected Outbound Referrals**. 3. Click **Save**. ## Delete Integration Deleting removes the integration from Fours. :::warning This may affect active co-sell opportunities and partner relationships. ::: ## Troubleshooting | Issue | Cause | Resolution | | --- | --- | --- | | Need to update settings | You need to change a Partner ID or sync parameter. | Open the card's actions menu, choose **Edit**, then click **Save**. | | OAuth authorization fails | The Google account used does not have Admin rights. | Sign in with a Google account that has **Admin** permissions in the Partner Network Hub. | | Sync not appearing | The Partner ID was entered incorrectly. | Open the card's actions menu, choose **Edit**, double-check your ID against the Partner Network Hub, and click **Save**. | ## FAQs **Can I set up a user-level integration for GCP Co-Sell?** No. This is an organization-level integration only, which keeps data consistent across your entire sales team rather than tied to a single user's account. **Does this integration sync both ways?** Yes. It supports bidirectional syncing of opportunities and referrals between Fours and the Partner Network Hub. :::tip If your organization has complex custom mapping requirements or you encounter issues during the OAuth flow, contact your Fours CSM or the Fours Support team for specialized assistance. ::: --- Source: https://doc.fours.com/integrations/github/ # GitHub ## Overview GitHub is a code hosting and collaboration platform for version control and software development. Integrate with GitHub to track repository activity, manage developer workflows, and correlate development data with sales operations. ### Org-Level vs User-Level > **Org-Level**: GitHub App for organization-wide access. Best for company-wide integrations with admin controls. > > **User-Level**: OAuth for personal GitHub account access. Use when you want to connect your personal repositories. ## Create Integration (Org-Level) ### Prerequisites - GitHub account with organization owner or admin privileges - GitHub API access (available on Free, Pro, and Team plans for limited API calls) ### Authenticate 1. Navigate to Settings > Integrations 2. Click "Connect GitHub" 3. Install the Fours GitHub App on your organization 4. Select the repositories to grant access to 5. Return to Fours to verify the connection ## Create User Integration Use user-level integration when you want to connect your personal GitHub account. 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to GitHub to authorize 3. Grant access to your GitHub repositories 4. Return to Fours to confirm connection :::warning Deleting the integration will remove access to GitHub immediately. ::: ## Fours AI Tools When GitHub is connected, the Fours AI agent can act on your repositories through Fours' built-in GitHub tools — no external MCP server is required. Capabilities are grouped below (~50 actions), plus an in-sandbox clone tool. > **Org-level and user-level**: Both are supported; user-level takes precedence when both are connected. Org (GitHub App) connections mint a short-lived installation token per run. | Capability | What the agent can do | |------------|-----------------------| | **Repositories & files** | Browse repositories and read or write file contents (e.g. `list-repos`, `get-file-contents`, `create-or-update-file`) | | **Branches, commits & tags** | Manage refs (e.g. `create-branch`, `get-commit`, `create-tag-object`) | | **Pull requests & reviews** | Open and merge PRs, request and submit reviews (e.g. `create-pull-request`, `merge-pull-request`, `submit-pull-request-review`) | | **Issues, comments & labels** | Full issue lifecycle (e.g. `create-issue`, `add-issue-comment`, `create-label`) | | **Releases** | Publish and edit releases and assets (e.g. `create-release`, `list-release-assets`) | | **Actions & workflows** | Inspect and trigger workflow runs and fetch logs (e.g. `list-workflow-runs`, `trigger-workflow-dispatch`, `rerun-workflow-run`) | | **Webhooks** | Manage repository webhooks (e.g. `register-webhook`, `deregister-webhook`) | In addition, the **`github_clone`** tool clones a repository (by `owner/repo` shorthand or HTTPS URL) into the agent's sandbox using your connected GitHub account. ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration from Fours. :::warning This does not delete your repositories or data in GitHub. Check GitHub for any additional OAuth app cleanup if needed. ::: --- Source: https://doc.fours.com/integrations/gitlab/ # GitLab ## Overview GitLab is a DevOps platform for source control, CI/CD, and project planning. Integrate with GitLab to automate developer workflows from Fours — browse projects and groups, read and write repository files, branches, and commits, manage issues and merge requests, and drive CI/CD pipelines, jobs, and releases. ### Org-Level vs User-Level > **Org-Level**: Organization-wide access via a GitLab **access token** — a service-account personal access token (preferred) or a Group Access Token. Best for shared, company-wide automation, and supports **self-managed** GitLab instances. > > **User-Level**: Personal GitLab.com access via OAuth. Use when you want to connect your own account and repositories. ## Create Integration (Org-Level) ### Prerequisites - A GitLab **access token** with the `api` scope. Options, in order of preference: - a **service account** personal access token (Premium/Ultimate), - a **Group Access Token** (Premium/Ultimate), or - a personal access token (any tier, including Free). - The token's identity must be a **member** of the groups and projects you want to access. - For **self-managed** GitLab, your instance host name (e.g. `gitlab.example.com`). ### Create a service-account access token (recommended) A service account is a machine user that isn't tied to a person, so the integration keeps working through staff changes. Setting one up is two steps: 1. **Create the service account** — as a group Owner, create a service account under your top-level group (**Group → Settings → Service accounts**, or via the API). 2. **Create an access token for it** — generate an access token for that service account with the `api` scope, and set an **expiration date** (GitLab caps this — typically 1 year). Then add the service account as a **member** of the groups and projects you want Fours to access (any role — it does not need to be Owner). :::warning Access tokens expire. Note the expiration date, **rotate the token before it lapses**, and **reconnect the integration** with the new token — otherwise GitLab calls start failing once it expires. ::: ### Authenticate 1. Navigate to Settings > Integrations 2. Click **Connect GitLab** 3. Paste your GitLab **access token** 4. For self-managed GitLab, enter your instance host name (GitLab.com is used by default) 5. Submit — the integration is verified automatically and its status updates to `verified` :::note For a Group Access Token or a personal access token instead, create it under **Group → Settings → Access Tokens** or **GitLab → User Settings → Access Tokens** — both need the `api` scope and both expire, so the rotation note above applies. See [GitLab access tokens](https://docs.gitlab.com/ee/user/profile/personal_access_tokens/). ::: :::warning An access token can only see resources whose group or project its identity is a **member** of. If lists come back empty, add the service account (or the token's bot user) as a member of the target group — creating a service account *under* a group does not by itself grant access to it. ::: ## Create User Integration Use user-level integration when you want to connect your personal GitLab.com account. 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to GitLab to authorize 3. Grant Fours access to your GitLab account 4. Return to Fours — the integration is connected and verified automatically ## Fours AI Tools When GitLab is connected, the Fours AI agent can automate GitLab through Fours' built-in tools (45 actions). Capabilities are grouped below. > **Org-level and user-level**: Both are supported; user-level takes precedence when both are connected. | Capability | What the agent can do | |------------|-----------------------| | **Projects & groups** | Create and manage projects and groups (e.g. `create-project`, `list-groups`) | | **Repository files** | Read and write repository files (e.g. `get-file`, `create-file`, `update-file`) | | **Branches & commits** | Manage branches and commits (e.g. `create-branch`, `create-commit`, `list-commits`) | | **Merge requests** | Full merge-request lifecycle (e.g. `create-merge-request`, `update-merge-request`) | | **Issues** | Issue CRUD (e.g. `create-issue`, `update-issue`) | | **CI/CD** | Drive pipelines and jobs and publish releases (e.g. `create-pipeline`, `retry-job`, `create-release`) | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration and revokes the stored credentials from Fours. :::warning This does not delete any GitLab data. You may also want to revoke the access token in GitLab (**User Settings → Access Tokens**, or the group's **Settings → Access Tokens**). ::: --- Source: https://doc.fours.com/integrations/gong/ # Gong ## Overview Gong is a revenue intelligence platform that captures and analyzes customer interactions across calls, meetings, and emails. Integrate with Gong to enrich sales data with conversation intelligence and track deal progression through call analytics. ### Org-Level vs User-Level > **Org-Level**: Organization-wide Gong access via API Key (Access Key + Access Key Secret). Best for company-wide analytics and reporting. > > **User-Level**: Personal Gong account access per user via OAuth. Connect your individual Gong account. ## Create Integration (Org-Level) ### Prerequisites - Gong account with API access - Gong Access Key and Access Key Secret (generated from Gong's API settings) ### Authenticate by API Key 1. Navigate to Settings > Integrations 2. Click "Connect Gong" 3. Enter your Gong **Access Key**, **Access Key Secret**, and **API Base URL** 4. Click **Create** to save the integration 5. Click **Verify** to confirm the connection ## Create User Integration Use user-level integration when you want to connect your personal Gong account. 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to Gong to authorize 3. Grant access to your Gong data 4. Return to Fours to confirm connection :::warning Deleting the integration will remove access to Gong immediately. ::: ## Fours AI Tools When Gong is connected, the Fours AI agent can work with your Gong revenue-intelligence data through Fours' built-in tools (67 actions). Capabilities are grouped below. > **Org-level and user-level**: Both are supported; user-level takes precedence when both are connected. | Capability | What the agent can do | |------------|-----------------------| | **Calls & recordings** | List and read calls, transcripts, and media, and find a company's calls by the CRM Account linked to each call or by its participants' email domain (e.g. `list-calls`, `find-account-calls`, `get-call-transcript`, `get-call-media`) | | **Users & workspaces** | Read users, workspaces, and settings (e.g. `list-users`, `get-workspace`) | | **Stats & analytics** | Pull activity and interaction aggregates (e.g. `get-stats-activity-aggregate`, `get-stats-interaction`) | | **Coaching & scoring** | Read scorecards, trackers, and coaching metrics (e.g. `list-scorecards`, `get-coaching-metrics`) | | **Gong Engage flows** | Manage flows, prospects, and step assignment (e.g. `list-flows`, `list-flow-prospects`) | | **CRM integration** | Register CRM integrations and upload entities and schema (e.g. `register-crm-integration`, `upload-crm-entities`) | | **Permissions & access** | Manage permission profiles and per-call user access (e.g. `list-permission-profiles`, `add-call-users-access`) | | **Meetings, library & data privacy** | Manage meetings and library folders and handle GDPR data requests (e.g. `create-meeting`, `list-library-folders`, `delete-data-for-email`) | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration from Fours. :::warning This does not delete your call recordings or data in Gong. Check Gong for any additional API key cleanup if needed. ::: --- Source: https://doc.fours.com/integrations/google-calendar/ # Google Calendar Allow Fours to access and manage your Google Calendar events, enabling automated scheduling and calendar management workflows. --- ## Overview Google Calendar is a time management and scheduling service developed by Google. It allows users to create, edit, and manage events and calendars, with support for reminders, guest invites, and integration with other Google Workspace services. By integrating Fours with Google Calendar, users can automate workflow tasks such as creating calendar events, managing schedules, sending invites, and synchronizing calendar data across systems for efficient appointment and meeting management. ### Org-Level vs User-Level > **User-Level**: Google Calendar is **user-level only**. Each person connects their own Google account with OAuth 2.0, and Fours acts on that person's calendars — never on a shared organization-wide calendar identity. > > **Org-Level**: **Not supported.** There is no organization-wide Google Calendar connection. The service-account (domain-wide delegation) path that this integration previously offered has been removed. :::note If your organization previously connected Google Calendar with a GCP service account, that path is gone. Each person who needs calendar automation should connect their own Google Calendar as a user integration instead, following the steps below. Other Google services are unaffected — Gmail, Google Drive, Google Cloud Storage, and BigQuery all still offer org-level service-account connections. ::: ## Create Integration ### Prerequisites - A Google account whose calendars you want Fours to work with. - Access to the [Fours Console](https://console.suger.io/) with your own Fours user account. No GCP project, service account, or Workspace admin action is required — the connection is a browser-based OAuth 2.0 authorization you complete yourself. ## Connect Your Personal Google Calendar (User Integration) You connect your own Google Calendar as a **User Integration**. This uses a secure OAuth 2.0 connection, so your Google password is never shared or stored. ### Step 1: Configure the User Integration 1. In the [Fours Console](https://console.suger.io/), go to **Settings > User Integrations**. 2. Find the **Google Calendar** card and click **Connect**. 3. You will be redirected to the Google sign-in page. Select the account you want to sync. 4. Review the requested access and click **Allow**. This enables Fours to view and manage your calendar events. 5. Once redirected back to Fours, click **Verify**. A **Verified** status confirms your calendar is successfully linked. ### Step 2: Manage Sync Preferences After the initial connection, you can tailor how Fours interacts with your schedule. - **Select Calendars**: If you have multiple calendars (for example, Personal, Team, or Holiday), specify which one Fours should use to create marketplace events. - **Update Connection**: To switch accounts or refresh an expired token, delete the current integration and repeat the setup process. - **Notification Alerts**: Ensure your Google Calendar mobile or desktop notifications are active to receive real-time alerts for synced marketplace milestones. ### Step 3: Revoke Access If you decide to stop using the integration, deleting it in Fours removes Fours' access. To fully clear the connection from Google's side: 1. Visit your [Google Account Security Settings](https://myaccount.google.com/security). 2. Go to **Your connections to third-party apps & services**. 3. Locate **Fours** and click **Remove Access**. ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the Google Calendar API directly. > **User-level only**: these tools run against the Google account *you* connected, so each person's Fours AI sees their own calendars. There is no org-level Calendar credential for them to fall back to — if you have not connected Google Calendar yourself, the tools below are unavailable to you. **Calendars** | Tool | Description | |------|-------------| | `googlecalendar_list_calendars` | List calendars the user has subscribed to | | `googlecalendar_get_calendar` | Get the user's view of a calendar | | `googlecalendar_describe_calendar` | Get canonical calendar metadata | | `googlecalendar_create_calendar` | Create a new secondary calendar | | `googlecalendar_update_calendar` | Update a calendar's summary, description, or timezone | | `googlecalendar_delete_calendar` | Permanently delete a secondary calendar | | `googlecalendar_clear_primary_calendar` | Delete all events from the primary calendar | | `googlecalendar_subscribe_to_calendar` | Subscribe to a shared calendar | | `googlecalendar_update_subscribed_calendar` | Update user-specific view of a subscribed calendar | | `googlecalendar_unsubscribe_calendar` | Unsubscribe from a calendar | | `googlecalendar_get_colors` | Get the color palette for events and calendars | | `googlecalendar_list_settings` | List the user's Calendar settings | | `googlecalendar_get_setting` | Get a single Calendar setting by ID | **Events** | Tool | Description | |------|-------------| | `googlecalendar_list_events` | List events (expands recurring series with singleEvents=true) | | `googlecalendar_get_event` | Get a specific event by ID | | `googlecalendar_create_event` | Create a new event (supports Google Meet, all-day, recurring) | | `googlecalendar_update_event` | Partially update an event | | `googlecalendar_delete_event` | Delete an event | | `googlecalendar_move_event` | Move an event to a different calendar | | `googlecalendar_quick_add_event` | Create an event from a natural-language string | | `googlecalendar_import_event` | Import an event from an external calendar | | `googlecalendar_list_event_instances` | List instances of a recurring event | | `googlecalendar_get_free_busy` | Query free/busy windows for one or more calendars | **Sharing (ACL)** | Tool | Description | |------|-------------| | `googlecalendar_list_calendar_acl` | List ACL rules for a calendar | | `googlecalendar_get_calendar_acl_rule` | Get one ACL rule by ID | | `googlecalendar_share_calendar` | Share a calendar with a user, group, or domain | | `googlecalendar_update_calendar_acl_rule` | Change the role of an existing ACL rule | | `googlecalendar_unshare_calendar` | Revoke a calendar share | ## Edit Integration > Editing is not supported for security reasons. To change configuration, delete the integration and create a new one. ## Delete Integration The Google Calendar integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the OAuth access and refresh tokens will be deleted immediately & permanently from Fours. No time window or methods to recover. Deleting it affects only **your** connection — other people in your organization who connected their own Google Calendar are unaffected. :::warning - Deleting the integration in Fours does not automatically revoke the permission you granted in Google. To fully disable access, also remove Fours from your Google account — see [Step 3: Revoke Access](#step-3-revoke-access) above. ::: --- Source: https://doc.fours.com/integrations/google-cloud-storage/ # Google Cloud Storage ## Overview Google Cloud Storage is a scalable, fully-managed object storage service for unstructured data. Integrate with Google Cloud Storage to enable Fours AI to list buckets, browse objects, read file contents, and inspect object metadata. ### Org-Level vs User-Level > **Org-Level**: Uses a GCP service account for organization-wide access to Cloud Storage buckets. Best for shared storage management. > > **User-Level**: Not applicable — Cloud Storage is an org-level integration only. ## Create Integration (Org-Level) ### Prerequisites - GCP project with Cloud Storage API enabled - Service account with Storage Admin role ### Authenticate by Service Account 1. [Create a service account](https://docs.cloud.google.com/iam/docs/service-accounts-create) in your GCP project 2. Grant the service account the `Storage Admin` role 3. [Create a service account key](https://docs.cloud.google.com/iam/docs/keys-create-delete#creating) and download the JSON file 4. Enter the service account email and upload the JSON key in Fours ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the Google Cloud Storage API directly. > **Org-level only**: Cloud Storage tools use the org-level service account credentials. | Tool | Description | |------|-------------| | `googlestorage_list_buckets` | List accessible GCS buckets for this integration | | `googlestorage_list_objects` | List objects in a bucket (supports prefix filter and directory-style listing) | | `googlestorage_get_object_metadata` | Get metadata for an object (size, content type, creation time) | | `googlestorage_read_object_content` | Read the text content of an object (text and JSON, up to 1 MB) | ## Edit Integration Editing is not supported. To change configuration, delete and recreate. ## Delete Integration Deleting removes the integration and revokes access. No recovery window. :::warning You must also remove the service account access in GCP Console. ::: --- Source: https://doc.fours.com/integrations/google-drive/ # Google Drive Allow Fours to manage your Google Drive seamlessly, including creating, deleting, updating, and sharing files and folders. --- ## Overview Google Drive is a versatile cloud storage and collaboration platform provided by Google. It offers users the ability to store, share, and collaborate on files and folders securely. With features like real-time editing, version history, and robust sharing options, Google Drive is a powerful tool for individuals and teams alike. By integrating Fours with Google Drive, you can streamline document management processes, automate tasks such as file organization, access control, and notifications, enabling efficient workflow automation tailored to your specific needs. ## Create Integration 1. [Create a service account](https://docs.cloud.google.com/iam/docs/service-accounts-create) in your target GCP project for Google Drive integration. 2. [Create the service account key](https://docs.cloud.google.com/iam/docs/keys-create-delete#creating), and download the associated JSON file. 3. Store the content of the key JSON file within the Fours console integration page. >Google Drive integration page in the Fours Console 4. Share files and folders in your Google Drive with the service account email address. If you want to grant Fours to create or update files, the service account needs to have necessary permissions. ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the Google Drive API directly. **Files** | Tool | Description | |------|-------------| | `googledrive_get_about` | Get the authenticated user's Drive account info and storage quota | | `googledrive_search_files` | Search for files using Drive query syntax | | `googledrive_list_recent_files` | List recently modified files | | `googledrive_get_file_metadata` | Get metadata for a file (name, type, size, owner, web link) | | `googledrive_read_file_content` | Read the text content of a file | | `googledrive_create_file` | Create a new file (supports converting to Google Docs/Sheets/Slides) | | `googledrive_create_folder` | Create a new folder | | `googledrive_update_file_content` | Overwrite the contents of an existing file | | `googledrive_update_file_metadata` | Rename, move, or update description of a file | | `googledrive_copy_file` | Make a copy of an existing file | | `googledrive_trash_file` | Move a file to Trash | | `googledrive_untrash_file` | Restore a trashed file | | `googledrive_list_shared_drives` | List shared drives (Team Drives) | **Sharing & Permissions** | Tool | Description | |------|-------------| | `googledrive_list_permissions` | List who has access to a file | | `googledrive_share_file` | Share a file with a user, group, domain, or everyone | | `googledrive_update_permission` | Change the role of an existing share | | `googledrive_unshare_file` | Revoke a share | **Comments & Replies** | Tool | Description | |------|-------------| | `googledrive_list_comments` | List comments on a file | | `googledrive_create_comment` | Add a comment to a file | | `googledrive_update_comment` | Edit the text of an existing comment | | `googledrive_delete_comment` | Delete a comment | | `googledrive_list_replies` | List replies under a comment | | `googledrive_create_reply` | Reply to a comment (supports resolve/reopen) | | `googledrive_delete_reply` | Delete a reply | **Revisions** | Tool | Description | |------|-------------| | `googledrive_list_revisions` | List the version history of a file | ## Edit Integration Editing an existing Google Drive integration is not supported. The practical way is to delete it and then re-create it from beginning. ## Delete Integration The Google Drive integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the service account with the key will be deleted immediately & permanently from Fours. No time window or methods to recover. :::warning - To completely delete the integration, You need to remove the service account access in your google drive as well. ::: --- Source: https://doc.fours.com/integrations/google-gemini/ # Google Gemini ## Overview By integrating your Gemini account with Fours, you can utilize your own Gemini API key. This allows you to access certain AI-powered features within Fours, with billing for API usage handled directly by Google. ### Org-Level vs User-Level > **When to use Org-Level**: Use org-level integration when you want organization-wide API key management with a centralized billing approach. > > **When to use User-Level**: Use user-level integration when each user wants to use their own Gemini API key with personal billing. ## Create Integration (Org-Level) 1. Navigate to the [Fours Console Integration](https://console.suger.io/settings?tab=integrations) page. 2. Find the **Gemini** integration and click the `Connect` button. 3. In the dialog that appears, provide the following information: - **API Key**: Your Gemini API key for accessing Gemini models. > Gemini integration API key entry dialog ## Create User Integration Use user-level integration for personal Gemini access. 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to Google to authorize 3. Enter your personal Gemini API key when prompted 4. Return to Fours to confirm connection :::warning Your API key is stored securely but deletion will revoke access immediately. ::: ## Edit Integration Editing the Gemini integration is not supported. To change the API key, you must delete the current integration and create a new one. ## Delete Integration You can delete the Gemini integration at any time. Please be aware that this action is irreversible and will permanently remove the integration credentials. --- Source: https://doc.fours.com/integrations/google-mail/ # Google Mail ## Overview Gmail, Google's email service, offers a comprehensive platform for communication and productivity. With features like advanced search capabilities, powerful filters, and seamless integration with other Google Workspace tools, Gmail is a cornerstone of modern email management. By integrating Fours with Gmail, users can leverage automation workflows to enhance email productivity. Tasks such as sending emails, applying labels for organization, and managing threads can be automated, improving efficiency and enabling customized email workflows tailored to specific needs. You can connect Gmail at two levels: - **Org-Level**: Connect once for your organization, so Fours can send automated email from a corporate mailbox that everyone's workflows share. There are **two connection methods** to choose from — a **Service account** with domain-wide delegation, or **Sign in with Google** — described below. - **User-Level**: Each user connects their own Gmail account via OAuth 2.0, so automated emails are sent from that person's own inbox. The Fours co-sell and commission emails a person's own actions trigger go out from their Gmail too — see [Send Co-Sell Emails from Your Gmail](#send-co-sell-emails-from-your-gmail). ### How the connection works Whichever method you use, Google issues the credential and Fours refreshes it for you — Fours never holds your Google password. What differs afterwards is *how* a given Gmail operation reaches Google. **Composing operations — creating, updating, sending and deleting drafts, and sending a message — are performed by Fours directly**, so a slow send is not cut short by an action timeout and never leaves you unsure whether the mail went out. Every other Gmail action (labels, filters, send-as aliases, vacation settings) runs through Fours' standard connector path. ```d2 shape: sequence_diagram you: "You or your Fours admin" google: "Google" suger: "Fours" agent: "Fours AI agent" you -> google: "Sign in with Google, or authorize a service account" google -> suger: "Credential — Fours refreshes it for you" { style.stroke-dash: 4 } compose: "Drafting and sending — run inside Fours" { agent -> suger: "Create, update, send or delete a draft; send a message" suger -> google: "Gmail call made directly — nothing queued, nothing cut short" google -> agent: "Draft id, or the message that was sent" { style.stroke-dash: 4 } } rest: "Everything else — labels, filters, send-as, vacation" { agent -> suger: "Run the action" suger -> google: "Routed through Fours' standard connector" google -> agent: "Result" { style.stroke-dash: 4 } } ``` :::note The org-level **Service account** method grants the send-only scope and produces a credential that impersonates a mailbox rather than an OAuth grant on it. That is enough for the standard Gmail actions, but **not** for the composing tools above — see [Fours AI Tools](#fours-ai-tools). ::: ## Create Integration (Org-Level) Org-level Gmail offers **two connection methods**. Both are set up from the same **Gmail** card under **Settings → Integrations**: click the **Connect** dropdown and pick the method you want. | Method | Choose this when | Scopes granted | |--------|------------------|----------------| | **Service account** | You run Google Workspace and want Fours to send as a corporate address (for example `sales@company.com`) with no person signing in and no user's token to expire. Requires a Workspace admin to authorize domain-wide delegation. | **Send only** (`gmail.send`) | | **Sign in with Google** | You want to authorize a mailbox directly, in a browser, with **no Workspace admin action required** — the fastest path, and the only one available if you are not on Google Workspace. | **Send and read** | :::tip[Which should I pick?] Pick **Service account** if you need a durable, admin-governed corporate sender and only ever need to *send*. Pick **Sign in with Google** if you want to be connected in a minute, cannot get a Workspace admin to authorize delegation, or need Fours to *read* mail as well as send it — the send-only scope on the service-account method is deliberate and cannot be widened after the fact. ::: Your organization connects **one way at a time**. Once connected, the Gmail card shows **"Connected via {method}"** — for example *Connected via Sign in with Google* — so you can always tell which method is in force. To switch methods, delete the integration and connect again with the other one. ![The Gmail card in Settings → Integrations with its Connect control opened — a two-item menu offering "Sign in with Google" and "Service account"](images/gmail-connect-dropdown.png) ### Method 1 — Service account (domain-wide delegation) This method is designed for company-wide automation where Fours sends email by impersonating a specific corporate address (for example, `sales@company.com`) without a user manually signing in. 1. [Create a service account](https://docs.cloud.google.com/iam/docs/service-accounts-create) in your target GCP project for Google Mail integration. :::info - Grant the service account with the IAM role `Service Account Token Creator` under the GCP project. ::: 2. [Enable the Gmail API](https://console.cloud.google.com/apis/api/gmail.googleapis.com/metrics) in the same Google project. 3. [Create the service account key](https://docs.cloud.google.com/iam/docs/keys-create-delete#creating), and download the associated JSON file. It is required for the following integration. 4. [Enable G-Suite Domain-wide Delegation](https://developers.google.com/workspace/guides/create-credentials#optional_set_up_domain-wide_delegation_for_a_service_account) for the service account. :::info - In the "OAuth Scopes" field, only select the scope `https://www.googleapis.com/auth/gmail.send`. ::: 5. Specify the impersonated email address, select the appropriate scopes configured in the previous step, and store the JSON key file contents within the Fours console integration page. :::info - Enter the Impersonation Email (a user email from your company) that Fours will impersonate to send emails on behalf of the user. **It MUST be a user email, instead of a group email**, since the group email can't be impersonated. - Select only the scope `https://www.googleapis.com/auth/gmail.send`. ::: > ![Google Mail Org Integration](images/google-mail-integration.jpg) :::warning[**Send as (Workspace user email)** is required] The connect form asks for **Send as (Workspace user email)** and this field is **not optional** for Gmail. A service account has no mailbox of its own, so a connection without it would be accepted and then fail on every send. It must be a valid Google Workspace **user** email address — a group address cannot be impersonated — and it must be one the domain-wide delegation you authorized in step 4 actually covers. ::: The default scope for this method is **send only** (`https://www.googleapis.com/auth/gmail.send`). Domain-wide delegation is all-or-nothing: a request asking for any scope your Workspace admin did not authorize fails entirely, so if you need Fours to read mail as well, use **Sign in with Google** instead. ### Method 2 — Sign in with Google (OAuth) This method authorizes a mailbox directly in the browser, using the same Google OAuth application as the user-level connection. **No Workspace admin action is required**, and it grants both **send and read** scopes. 1. In the Fours Console, go to **Settings → Integrations** and find the **Gmail** card. 2. Open the **Connect** dropdown and choose **Sign in with Google**. 3. You are redirected to the Google sign-in page. Sign in with the mailbox your organization should send from — this is the account every workflow in your organization will send as, so use a shared or role mailbox rather than a personal one. 4. Review the requested access and click **Allow**. 5. Once you are redirected back to the Fours Console, click **Verify**. A **Verified** status confirms the connection is ready. ![The Integrations catalog — the Gmail card showing "Connected via Service account", the label that tells you which of the two org-level methods is in use](images/gmail-connected-via.png) :::caution Because this is a normal OAuth grant on a real Google account, it is tied to that account's continued existence and consent. If the mailbox owner leaves and the account is deleted, or someone revokes Fours' access from their Google account, org-wide sending stops until you reconnect. A shared/role mailbox — or the service-account method — avoids that. ::: ## Create User Integration User-Level integration is personal and precise. It lets Fours send emails that look like they came from you, while automation handles the repetitive work. - **OAuth 2.0 Security**: Fours never sees, asks for, or stores your Google password. The connection is a secure, token-based handshake. - **Responsive automation**: Send automated private offer links and follow-up sequences the moment a buyer hits a milestone. - **Thread management**: Keep your deal discussions organized without jumping between tabs. 1. In the Fours Console, go to **Settings → Integrations** and scroll to the **User Integrations** section. Locate the **Gmail** card and click **Connect**, then click **Start connection** in the **Connect Gmail** dialog. > ![Google Mail Connect Now](images/user-integration-connect-gmail-to-suger-1.jpg) 2. You will be redirected to the Google sign-in page. Select the account you want to use for your marketplace deals. 3. Review the request and click **Allow**. This grants Fours the permissions needed to read and send emails related to your marketplace workflows. > ![Google Mail User Consent](images/user-integration-connect-gmail-to-suger-2.jpg) 4. When the dialog shows **Gmail is connected.**, click **Close**. The **Gmail** card now shows a green check mark, which confirms Fours is ready to send on your behalf. ## Send Co-Sell Emails from Your Gmail A user-level Gmail connection also changes who sends your co-sell email. When **your own action** in Fours triggers a Fours co-sell or commission email, Fours sends it from your connected Gmail instead of from that email's usual sender. That covers sharing a deal with a partner, accepting or declining one, marking it Closed Won or Closed Lost, updating a deal, removing a partner, proposing or approving commission terms, and marking a commission payment sent or confirming it. - **It is the same email.** It keeps the subject and threading that Fours' default sender uses (see the [Partners notification scopes](/settings/email-notification/#partners)) and the same recipients, including the deal's activity address on Cc — so replies sent with **Reply all** still reach the deal's activity feed. Because the email comes from your mailbox, a plain **Reply** reaches you directly, and a copy stays in your Gmail **Sent** folder. - **There is no setting.** Connecting Gmail as a [user integration](#create-user-integration) turns it on; disconnecting turns it off. - **If your Gmail can't send, the email still goes out.** If you have no Gmail connection, or its access has expired or been revoked, Fours sends the email from the custom sender configured for that notification if there is one, otherwise from Fours' default sender. - **Connect in each organization you act from.** A user integration belongs to one Fours organization, so an email goes out from your Gmail only when you connected Gmail in the organization you acted in. - **Partner organizations can do the same.** A partner's users can connect their own Gmail at user level, so the emails their actions trigger come from their own mailboxes. - **One-click links work the same way.** When someone completes an action from a one-click link in a co-sell email, the follow-up email goes out from their own connected Gmail, as if they had acted in the console. These are **never** sent from your mailbox: - Emails Fours sends on its own — automatic acceptance, scheduled jobs, and webhooks. - Emails triggered by actions in the Salesforce or HubSpot app, or through the API. - Copies that carry a personal one-click action link. Those always come from Fours' default sender. - Copies addressed to recipients that another organization added in its own notification settings. - Other notifications, such as offer and entitlement emails. ```d2 direction: down act: "Your action triggers a Fours\nco-sell or commission email" personal: "Copy carries a personal\none-click action link?" { shape: diamond } yours: "Eligible for your mailbox, and\nyour user-level Gmail can send?" { shape: diamond } custom: "Custom sender configured\nfor this notification?" { shape: diamond } gmail: "Sent from your Gmail" configured: "Sent from the custom sender" suger: "Sent from Fours' default sender" act -> personal personal -> suger: "yes" personal -> yours: "no" yours -> gmail: "yes" yours -> custom: "no" custom -> configured: "yes" custom -> suger: "no" ``` :::note Only Gmail sends these emails on your behalf. Your own connected [Microsoft Outlook](/integrations/microsoft-outlook/) account is never used for them, because Outlook cannot keep them in the deal's single email thread. ::: ## Fours AI Tools When Gmail is connected, the Fours AI agent works your mailbox through Fours' built-in tools. The composing tools are the ones you will name most often; they carry a `google_email__` prefix. | Capability | What the agent can do | |------------|-----------------------| | **Compose a draft** | Write a new Gmail draft from a subject, body and recipients — including Cc, Bcc, an HTML body and file attachments — and get back the draft's id. The draft is saved, never sent (`create-draft`) | | **Revise a draft** | Replace an existing draft's contents. The whole message is rewritten from the call, attachments included, so the agent restates the complete draft rather than patching one field (`update-draft`) | | **Send a draft** | Send a draft that is already saved. Irreversible — the recipient has it immediately (`send-draft`) | | **Discard a draft** | Delete a draft without sending it (`delete-draft`) | | **Send a message** | Compose and send in one step, without saving a draft first, attachments included. Irreversible. Can reply inside an existing conversation rather than starting a new one (`send-message`) | | **Everything else in Gmail** | Labels, filters, send-as aliases, vacation settings and the rest of the Gmail surface remain available as standard actions on the connection | You never have to hand the agent a pre-assembled raw email: it supplies the recipients, subject and body as ordinary fields, and Fours builds the message — including correct handling of non-ASCII subject lines. **Attachments.** `create-draft`, `update-draft` and `send-message` take files to attach, each as a file name, a MIME type and the file's contents in base64. The base64 that the `get-attachment` action returns for a received attachment is accepted as it is, so the agent can attach a file it read from another message. Fours checks every file before anything reaches your mailbox and refuses the call if a file's contents are not valid base64 or the files add up to more than 18 MB. Because the contents pass through the agent, attaching suits small files — a large attachment may not reach the agent whole, so forward that email from Gmail yourself. When the agent revises a draft, any attachment it does not pass again is removed. :::warning[A service-account org connection does not get the composing tools] The composing tools above need an OAuth grant on a real mailbox. An **org-level Gmail connection created with the Service account method does not have one**, so on that connection the agent gets **none** of `create-draft`, `update-draft`, `send-draft`, `delete-draft` or `send-message` — only the standard Gmail actions remain. If you want the agent to draft and send, connect Gmail with **Sign in with Google** at the org level, or have each person connect their own Gmail as a [user integration](#create-user-integration). The service-account method is still the right choice when all you need is automated *sending from workflows* out of a durable corporate address. ::: :::info Sending is not reversible and the agent knows it: `send-draft` and `send-message` deliver immediately, with no recall window. Prefer having the agent create a draft and reviewing it yourself before a send. ::: :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration > Editing is not supported for security reasons. To change configuration, delete the integration and create a new one. :::info - If your OAuth token expires, or you change your Google password or rotate your GCP service account keys, delete the integration in Fours and recreate it to refresh access. - When switching from a personal to a corporate account, delete the current integration first to ensure no stale tokens remain. - The org-level Gmail card tells you when its stored credential has stopped working, so you do not have to discover it from a failed send — see [Connection health](/integrations/#connection-health). ::: ## Delete Integration The Google Mail integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the service account key and access tokens will be deleted immediately & permanently from Fours. No time window or methods to recover. :::warning - For a Service Account integration, also delete the service account and its key in the GCP Console to fully revoke access. - Deleting the integration in Fours does not automatically revoke permissions granted in Google. To fully disable access, the user must also revoke the application's permissions in their Google account. Steps to revoke Google permissions: 1. Go to Google Account → Security 2. Open Your connections to third-party apps & services 3. Locate the Fours application with Google Mail access 4. Click Remove access ::: --- Source: https://doc.fours.com/integrations/google-workspace-sso/ # Google Workspace SSO Sign in with Google Workspace, and let three Google groups decide who is in your Fours organization. :::info Fours was formerly named Suger, and some labels in the Fours console still say Suger. ::: ## Overview A Google Workspace SSO connection lets your employees sign in to Fours with their Google Workspace account. Turning on **Directory Sync** for the connection goes further: your Google directory decides who belongs to your Fours organization and with which role, so you manage access in Google Workspace instead of inviting people one by one. **Supported features:** - **Single sign-on** with Google Workspace accounts, through a dedicated login link for your organization. - **Directory Sync**, which makes your organization's members follow three Google groups: - **Add members:** a direct member of one of the three Google groups gets access without an invitation. - **Change roles:** moving someone to another of the groups changes their Fours role. - **Remove members:** someone who leaves all three groups, or is suspended or deleted in Google Workspace, loses access. Google Workspace does not push changes to Fours. Fours reads your directory on a schedule instead: ```d2 direction: right google: "Google Workspace\nusers, suspensions,\nthe three groups" dirsync: "Directory Sync\nreads the directory\nabout every 30 minutes" fours: "Fours\napplies group membership\nevery hour" org: "Your Fours organization\nmembers and roles" google -> dirsync: "read-only" dirsync -> fours: "users and groups" fours -> org: "adds, changes roles,\nremoves" ``` A change you make in Google Workspace therefore reaches Fours within about an hour and a half: up to 30 minutes for the directory read, then up to an hour for Fours to apply it. To apply a change sooner, click **Sync now** in the Directory Sync panel: Fours applies group membership a few minutes after that read finishes. Once applied, a role change or a removal takes effect without the member signing out. ### Roles come from three Google groups Create these groups in Google Workspace with exactly these names (capitalization does not matter): | Google group | Fours role | | --- | --- | | `Fours Admins` | Admin | | `Fours Editors` | Editor | | `Fours Viewers` | Viewer | - **Highest role wins.** Someone in more than one of the groups gets the highest of their roles. - **Add people directly.** Only direct members count. A group nested inside one of them is not read, so its members get no access. - **Primary domain only.** Only accounts whose primary email address is on the domain you entered for the connection are added. Users on secondary domains or domain aliases are not. ### Members Directory Sync manages A member added or adopted by Directory Sync shows a **Google group** badge under their role in **Settings > Users & Roles**; hover over it to see which group manages them. Their role and their membership come from Google Workspace, so the edit and remove buttons are turned off for them in Fours: change their group membership in Google Workspace instead. Members you invited yourself are left alone — unless they are also in one of the groups. Directory Sync then takes them over: they get the group's role, **even if it is lower than their current one**, and are managed from then on, including removal when they leave the groups. > Users & Roles table where members added from Google groups show the Google group badge and disabled edit and remove buttons, next to manually invited members --- ## Configuration Steps :::info **Prerequisites:** - You are an admin of your Fours organization. - You can create an OAuth client in a Google Cloud project. - A **super admin** of your Google Workspace (or Google Cloud Identity) account is available to grant directory access in Step 4. ::: ### Step 1: Create the Google OAuth client The connection signs your employees in through an OAuth client that you own. In the Google Cloud project that will own it: 1. Enable the **Admin SDK API**. Directory Sync reads your users and groups through it. 2. On the **OAuth consent screen**, set the user type to **Internal**. 3. Create an **OAuth client ID** of type **Web application**, and note its **Client ID** and **Client Secret**. You add its redirect URIs in Step 4. The **Set up SSO** dialog in Step 3 lists the same steps under **Using Google Workspace? Prepare an OAuth client first**, together with the JavaScript origins and redirect URIs to register, so you can also register them on the OAuth client right away. ### Step 2: Create the three groups In Google Workspace, create the groups `Fours Admins`, `Fours Editors` and `Fours Viewers`, and add people to them directly. :::warning Put the people who administer Fours in `Fours Admins`, or in none of the groups. Directory Sync gives everyone in a group that group's role: an admin who is only in `Fours Viewers` becomes a Viewer. ::: ### Step 3: Create the SSO connection 1. In the Fours console, go to **Settings > SSO** and click **Set up SSO**. > SSO settings page in the Fours console 2. Optionally enter a **Connection Name**, then click **Continue**. Fours opens the SSO setup wizard in a new tab. 3. Choose **Google Workspace (OIDC)**, then enter your Google Workspace **domain** and the **Client ID** and **Client Secret** from Step 1. 4. Test the connection with a Google Workspace account and enable it. Back in **Settings > SSO**, the connection now appears with a **Directory Sync** button. :::note Google Workspace connections do not use SCIM: Google does not push user changes, so there is no SCIM section for them. Directory Sync replaces it. ::: ### Step 4: Turn on Directory Sync 1. On the connection, click **Directory Sync** to open its panel. 2. Register the URLs the panel lists on the OAuth client from Step 1 — **all** of the **Authorized JavaScript origins** and **all** of the **Authorized redirect URIs**. Each has a copy button. After you enable Directory Sync, the same list stays available under **Google OAuth client settings**. > Directory Sync panel before it is enabled, listing the setup checklist, the authorized JavaScript origins and redirect URIs to register, and Enable Directory Sync :::warning The setup wizard shows only one redirect URI. Register every one the Directory Sync panel lists: without them, sign-in to Fours fails with Google's `redirect_uri_mismatch` error even though the wizard's test passed. ::: 3. Click **Enable Directory Sync**. 4. A Google Workspace **super admin** clicks **Grant admin consent**, signs in with their super admin account and clicks **Allow**. This gives read-only access to your users and groups. The panel shows **Admin consent granted** once it is done. 5. Click **Sync now** to read the directory for the first time. > Directory Sync panel waiting for admin consent, with the Grant admin consent button, the Admin SDK API reminder and Sync now After you click **Sync now**, the panel says **Directory Sync is active**. Once the first read finishes, the panel lists the three groups with their member counts (all direct members of each group, so the count can be higher than the number of Fours members). From now on the directory is read automatically about every 30 minutes. > Active Directory Sync panel showing the last sync, the three groups with their member counts, Sync now, Disable and the employee login link :::note **Sync now** reads the directory right away, and Fours applies group membership a few minutes after that read finishes, without waiting for its hourly run. It can run once every 30 minutes, counting automatic reads — if you click it sooner, the panel tells you a sync ran in the last 30 minutes and to try again later. ::: ### Step 5: Share the login link Give your employees the **Employee login link** shown at the bottom of the Directory Sync panel. The people in the groups become members of your organization a few minutes after the first sync finishes — before they ever sign in. :::warning Employees must sign in through the employee login link. The plain **Continue with Google** button on the Fours sign-in page does not sign them into your organization. ::: --- ## What happens when someone leaves For members Directory Sync manages: | In Google Workspace | In Fours | | --- | --- | | Removed from all three groups | Removed from your organization | | Deleted | Removed from your organization | | Moved to another of the groups | Their role changes | A **suspended** account is treated differently: it is removed from your organization — and from any other Fours organization it belongs to — even if you invited the person yourself. If the account is reactivated and is still in one of the groups, Directory Sync adds it back. Memberships the groups did not manage are not restored. Each of these reaches Fours within about an hour and a half, or a few minutes after you click **Sync now**. Once someone is removed, their existing session no longer works in your organization, and signing in again does not bring them back. :::note API clients belong to your organization, not to the member who created them. Removing a member does not revoke the API clients they created — review them when someone leaves (see [API Access](/settings/oauth-app/)). ::: ## Disable Directory Sync On the Directory Sync panel, click **Disable**, then **Disable Directory Sync** to confirm. Fours stops reading your Google Workspace directory. Everyone keeps their access and role, and becomes an ordinary member you manage in **Settings > Users & Roles**. Deleting the SSO connection does the same for its members: they stay in your organization as ordinary members, but can no longer sign in through that connection. ## Limits - **Directory size:** Directory Sync supports connections with up to 1,000 users. For a larger directory, contact [support@suger.io](mailto:support@suger.io). - **Safety stop:** if a single run would remove more than 5 members and more than a fifth of the members Directory Sync manages, Fours makes no changes for that connection — no additions, role changes or removals — and keeps skipping every hourly run until fewer removals are pending. This guards against a group deleted by mistake. If you meant to remove that many people, contact [support@suger.io](mailto:support@suger.io). ## Troubleshooting | What you see | What to do | | --- | --- | | The panel asks a super admin to open the consent link | A Google Workspace super admin must click **Grant admin consent** and **Allow**. | | The panel says to contact support for the consent link | Contact [support@suger.io](mailto:support@suger.io) for the consent link. | | **Sync now** says no sync was started because admin consent is still missing | Grant admin consent first, then click **Sync now** again. | | Consent is granted but the sync still fails | Enable the **Admin SDK API** in the Google Cloud project that owns the OAuth client, then click **Sync now**. Fours cannot check this setting for you. | | `redirect_uri_mismatch` when an employee signs in | Register every JavaScript origin and redirect URI listed under **Google OAuth client settings** in the Directory Sync panel on the OAuth client. | | An employee lands on **Join an Organization** | They signed in with the plain **Continue with Google** button; or they are not a direct member of one of the groups; or their primary email is outside the connection's domain; or the change has not reached Fours yet (allow about an hour and a half, or click **Sync now** and wait a few minutes). Send them the employee login link, and check their group membership. | | A group shows "not found in the directory" | Create the group with the exact name, or wait for the next directory read after creating it. | | A group shows "more than one group has this name; this role is skipped" | Two Google groups share one of the three names. Rename or delete the extra group. While the names are ambiguous, Fours removes no one and lowers no one's role. | | The last sync shows **failed** | Read the error shown under the last sync time and fix it in Google Workspace. One known cause is two groups whose names differ only in capitalization (for example `Fours Viewers` and `fours viewers`): rename or delete one. | | Someone left the groups but is still a member | Allow about an hour and a half, or click **Sync now** and wait a few minutes. If it takes longer, the safety stop under [Limits](#limits) may be holding all changes back. | --- Source: https://doc.fours.com/integrations/hubspot/ # HubSpot Sync leads & opportunities with HubSpot for co-sell --- :::info Fours was formerly named Suger. Inside HubSpot, the app — its marketplace listing, the **Suger** deal card and tab, and labels such as **Suger Predicted Engagement Score** — still uses the name Suger until the app is renamed. ::: ## Overview Integration with HubSpot enables the bi-directional referral & syncing between HubSpot opportunities and other partners like [APN Customer Engagements Program](https://aws.amazon.com/partners/programs/ace/) and thus makes co-selling possible. ### How the integration works | | | | --- | --- | | **Direction** | Two-way. Referrals raised in HubSpot are pushed to the cloud partner programs; referral and marketplace state flows back onto the HubSpot records. | | **Source of truth** | HubSpot owns the deal and company records. Fours owns referrals, offers and marketplace state, and writes them onto the linked HubSpot records. | | **Scope** | Organization-level — one HubSpot connection per Fours organization, authorized through OAuth. | | **Scheduled jobs** | CRM enrichment every **2 hours**, processing at most **10,000 records** per run by default. | | **Credentials** | An OAuth authorization granting the scopes listed below. Fours requests a fixed set of required scopes plus optional ones that unlock individual features — a missing optional scope disables just that feature rather than the whole connection. | ### When something fails - **[Referral-state](#referral-state) sync is on-demand, not scheduled.** Unlike enrichment, it runs only when you press **Sync**. If a write fails, the state does not repair itself on a later pass — press Sync again. - **Enrichment writes go out in batches of 100 and a failed batch does not stop the run.** Failures are counted and the next batch proceeds, so one rejected record cannot block the rest of your deals. HubSpot's per-record errors inside a partially-successful batch are captured individually. - **HubSpot API calls are not retried.** Requests have a 90-second timeout and a failure surfaces immediately rather than being retried in the background — deliberate for write paths, where a blind retry risks duplicating records. Enrichment activities themselves retry 2 to 3 times with backoff. - **A very large search returns partial results rather than an error.** Paging stops after 100 pages (up to 20,000 records) and the result is flagged as truncated. Narrow the filter if you expect more. - **Referrals are de-duplicated by HubSpot deal ID, and contacts by email**, so re-running a sync does not create a second copy of something Fours already linked. ### Which deal contact becomes the customer contact A HubSpot deal can carry several contacts, and HubSpot has no way to mark one of them as the deal's primary contact. So when a co-sell field mapping reads a deal's contact properties, Fours reads **one** contact per deal. The default outbound mappings do this for the referral's customer contact: AWS and Microsoft read `contacts.firstname`, `contacts.lastname`, `contacts.email`, `contacts.phone` and `contacts.jobtitle`; Google Cloud reads the same properties except `contacts.jobtitle`. The contact is chosen like this: 1. **Check how many companies the deal has.** A deal with one associated company, or none, uses its first contact — there is no company check. 2. **With two or more companies, find the deal's primary company** — the company marked **Primary** on the deal, or the first company listed when none is marked. 3. **Take the first contact on the deal that belongs to that company** — the first, in the order HubSpot lists the deal's contacts, that is itself associated with the primary company. 4. **Otherwise send no customer contact.** If no contact on the deal is associated with the primary company, the customer contact fields stay empty. Fours does not fall back to another contact: on a multi-company deal such as a reseller deal, that contact is usually the reseller's, not the end customer's. ```d2 direction: down deal: "HubSpot deal" has_company: "Deal has two or more\nassociated companies?" { shape: diamond } first_contact: "Customer contact =\nthe deal's first contact" primary: "Primary company =\nthe one marked Primary,\nelse the first listed" match: "Any deal contact associated\nwith the primary company?" { shape: diamond } chosen: "Customer contact =\nthe first such contact" none: "No customer contact\nfields left empty" deal -> has_company has_company -> first_contact: "no" has_company -> primary: "yes" primary -> match match -> chosen: "yes" match -> none: "no" ``` The same rule applies everywhere Fours fills a referral from a HubSpot deal — the pre-filled referral form in the Fours HubSpot app (see [Create Co-Sell](/hubspot-app/hubspot-app-cosell/)), referrals shared automatically, and **Test Field Mapping** in [co-sell configuration](/cosell/cosell-configuration/#test-field-mapping). :::tip If the customer contact comes up empty, open the deal in HubSpot and associate the end customer's contact with the deal's primary company, then open the co-sell form again — a new referral's form re-reads the deal each time it opens. You can also type the contact into the form before you submit it. ::: ## Prerequisite It is strongly recommended that you create a user that is dedicated for integration purpose, either for Fours alone or for all integrations. After integration, all Fours' operation on your HubSpot will be performed by this user. We need the following permissions: - `crm.schemas.companies.read` - `crm.schemas.companies.write` - `crm.schemas.contacts.read` - `crm.schemas.contacts.write` - `crm.schemas.deals.read` - `crm.schemas.deals.write` - `crm.objects.companies.read` - `crm.objects.companies.write` - `crm.objects.contacts.read` - `crm.objects.contacts.write` - `crm.objects.deals.read` - `crm.objects.deals.write` - `crm.objects.owners.read` To satisfy this requirement, you need to ensure the delegation user has "view" and "edit" permissions on CRM contacts, companies, and deals, as well as permission to "edit property settings" and "App Marketplace access" for installing the app. For example, the following permission set would suffice: > CRM permissions for contacts, companies, and deals > Property settings and App Marketplace access permissions ## Create Integration We created a HubSpot App called "Suger". You can easily complete the integration with the following steps: 1. Click the "Connect" button on the "Integrations" page. 2. HubSpot authorization page will open up in a new tab, asking you to login (if you haven't yet), and select an account to start the integration. > HubSpot authorization page for account login 3. Login and select your account, and click "Choose Account". 4. Review the permissions, and click "Connect App". 5. The integration status will become "Created". Now locate the HubSpot integration in the view, and click "Verify". > Verify button on the HubSpot integration 6. Fours will attempt to read a few opportunities to verify the connection, after which the status will become "Verified" and start working. 7. Now you are all set! ## Referral State **The Referral State property is a custom HubSpot deal property that records which cloud partners (AWS, Azure, GCP) a deal has already been shared with for co-sell.** Once it is configured, Fours keeps it in sync, so you can filter your HubSpot deals by their referral state directly in the Fours Console. Setting this up has three parts: create the custom property in HubSpot, configure it in Fours, then use it to filter your deals. ### Create the Custom Property in HubSpot Before configuring the property in Fours, create a custom property in HubSpot. If you already have a suitable property, you can skip this section. #### Step 1: Create a property group 1. In HubSpot, go to **Settings** and open the **Properties** menu under **Data Management** in the left sidebar. 2. Select **Deal** object properties and click the **Groups** tab. 3. If an existing group meets your needs, use it. Otherwise, click **New Group** to create one. ![HubSpot deal property groups](images/inline_18476e-62691_1.png) #### Step 2: Create the new property 1. In **Settings**, open the **Properties** menu under **Data Management** and select **Deal** object properties. 2. Switch to the **Properties** tab and click **New Property**. 3. Ensure the object type is set to **Deal** and choose the appropriate group (the one you created earlier, if applicable). 4. Label the property **Referral State** (or any name you prefer). 5. Set the field type to **Multiple Checkboxes** with at least three options: **AWS**, **Azure**, and **GCP**. 6. Click **Create**. Your new property now appears in the property list. :::warning Each option's internal value must be exactly **AWS**, **Azure**, or **GCP**, including case. **Verify** checks for those three values, and the property must be a **Multiple Checkboxes** field. ::: ### Configure in Fours #### Step 1: Set the Deal Referral State property 1. Edit the HubSpot integration in the [Fours Console](https://console.suger.io/settings?tab=integrations). 2. In the **Advanced** section, find the **Deal Referral State Property** option. 3. Enter the label of the property you created in HubSpot. 4. If the property is not listed, click the refresh button to reload it. 5. Click **Verify**. If everything is correct, click **Save** to apply the settings. ![Deal Referral State Property setting in Fours](images/inline_18476e-62691_2.png) #### Step 2: Sync referral state with HubSpot 1. Click the **Sync** button on the HubSpot integration. 2. It takes several minutes to update the referral state of all deals. ### Use the Property in Fours Once the referral state is syncing, you can filter your HubSpot deals in the Fours Console based on whether they have already been shared. #### Filter out deals that were shared before 1. Click **Co-Sell** in the left sidebar and switch to the **HubSpot** tab. 2. Click **Filters** and add a new filter. 3. Set the field name to **Referral State** (or your own property name if different). 4. Set the operator to **IS NULL**. ![Filter for deals with no referral state](images/inline_18476e-62691_3.png) #### Filter deals already shared with cloud partners 1. Click **Co-Sell** in the left sidebar and switch to the **HubSpot** tab. 2. Click **Filters** and add a new filter. 3. Set the field name to **Referral State** (or your own property name if different). 4. Set the operator to **IS IN** and select the cloud partners (AWS, Azure, GCP) you want to include. ![Filter for deals shared with selected cloud partners](images/hubspot-referral-state-property-settings-1.png) ## CRM Enrichment CRM Enrichment allows you to automatically enrich HubSpot records with intelligence signals from Fours. This feature syncs valuable marketplace and engagement data directly to your CRM records, giving your sales team actionable insights without leaving HubSpot. ### Overview With CRM Enrichment, you can: - **Automatically populate CRM properties** with intelligence signals (engagement scores, marketplace metrics) - **Configure multiple record types** (e.g., Deals, Companies) with different enrichment rules - **Use JSON queries** to target specific records for enrichment - **Map intelligence fields** to custom HubSpot properties ### Prerequisites Before configuring enrichment, ensure you have: 1. **Custom properties created** in HubSpot to store the intelligence data ### Creating Custom Properties in HubSpot You need to create custom properties in HubSpot to store the intelligence signals. For each signal you want to sync: 1. Go to **Settings** → **Data Management** → **Objects** → Select your object (e.g., Deals) > HubSpot Data Management Objects settings page 2. Click **Manage Deal properties** (or the equivalent for your object) 3. Click **Create property** > Create property button in HubSpot 4. Enter a **Property label** (e.g., "AZURE Engagement Score") and select the **Object type** and **Group** > Property label, object type, and group fields 5. Choose the appropriate **Field type** (e.g., **Single-line text** for scores and general data) > Field type selection for the custom property 6. Click **Create** to save the property ### Configuring Enrichment 1. Navigate to **Fours Console** → **Settings** → **Integrations** → **HubSpot** 2. Click **Edit** to open the integration settings 3. Go to the **Enrichment** tab 4. Click **Add CRM Record** to create a new enrichment rule > Add CRM Record enrichment configuration in Fours Console For each configuration, specify: | Setting | Description | |---------|-------------| | **CRM Record Type** | The HubSpot object to enrich (e.g., Deals, Companies) | | **Field Mappings** | Map intelligence fields to your custom HubSpot properties | | **HubSpot Search Query (JSON)** | JSON query to filter which records to enrich | | **Update records that already have enrichment data** | Controls when previously enriched records are refreshed: **Never**, **Immediately**, or **Every N days** (default: 30 days) | | **Max Records Per Sync** | Maximum number of records to process per sync run (default: 10,000, minimum: 1,000) | After entering your query, click **Validate Query** to verify it is valid and see how many records match. This helps ensure your enrichment rule targets the right set of records before saving. ### Available Intelligence Fields Intelligence signals are derived from multiple data sources: - **Cloud partner data** — Engagement scores sourced directly from cloud partner programs (e.g., AWS Partner Network, Azure Partner Center, Google Cloud Partner Network). - **Marketplace activity** — Public marketplace metrics such as listing counts, review counts, and purchase history across AWS, Azure, and GCP marketplaces. The following intelligence signals can be mapped to your CRM properties: **AWS Signals** - AWS Engagement Score - AWS Marketplace Count - AWS Marketplace Review Count - AWS Marketplace Purchase Count **Azure Signals** - Azure Engagement Score - Azure Event Score - Azure Usage Score - Azure Marketplace Count - Azure Marketplace Review Count - Azure Marketplace Purchase Count **GCP Signals** - GCP Engagement Score - GCP Marketplace Count - GCP Marketplace Review Count - GCP Marketplace Purchase Count ### Example Configuration To enrich Deals in the "Qualified to Buy" stage with AWS engagement data: 1. **CRM Record Type**: Deals 2. **Field Mappings**: - `AWS Engagement Score` → `aws_engagement_score` 3. **HubSpot Search Query (JSON)**: ```json { "filterGroups": [ { "filters": [ { "propertyName": "dealstage", "operator": "EQ", "value": "qualifiedtobuy" } ] } ] } ``` ### How Enrichment Works #### Sync Schedule Fours runs a scheduled enrichment sync **every 2 hours**. During each sync, Fours automatically processes all configured enrichment rules for your organization. #### Enrichment Process Each sync goes through the following steps: 1. **Query your HubSpot account** using the configured JSON search query to identify records that need enrichment. 2. **Look up intelligence data** for each matching record based on the company's domain. 3. **Update the mapped properties** in HubSpot with the latest intelligence values. #### Update Mechanism Fours uses a smart two-step approach to ensure efficient and complete data coverage: - **Step 1 — Enrich new records**: Every sync prioritizes records that have **not been enriched yet** (where the mapped properties are still empty). This ensures newly added or previously missed records receive intelligence data first. - **Step 2 — Refresh existing records**: Once all new records have been enriched, Fours begins a **refresh cycle** — rotating through previously enriched records in batches to keep data up to date. This rotation continues across multiple syncs until all records have been refreshed, then a new cycle begins. The **Update records that already have enrichment data** setting controls how the refresh cycle behaves: | Setting | Behavior | |---------|----------| | **Never** | Only enrich records that have not been enriched before. Previously enriched records are never updated. | | **Immediately** | Continuously rotate through all records, refreshing data without delay between cycles. | | **Every N days** | Wait N days after completing a full refresh cycle before starting the next one (default: 30 days). | #### Records Per Sync Each sync processes up to a configurable maximum number of records. For HubSpot, the default and maximum is **10,000**. The minimum configurable value is **1,000**. If your query matches more records than the configured limit, the remaining records are handled automatically: - **New records (Step 1)**: Unenriched records will be picked up in the next sync since they still have empty fields — no progress tracking is needed. - **Refresh cycle (Step 2)**: Fours tracks its cursor position across syncs to rotate through all records. For example, with 30,000 records and a limit of 10,000 per sync, the refresh cycle completes in 3 runs. Once a full cycle finishes, the next one starts based on your **Update records that already have enrichment data** setting. #### Tracking Enrichment Progress To monitor the status of your enrichment sync: 1. Go to the enrichment configuration for your record type 2. Expand **Advanced Configuration** 3. Click **Check Progress** The progress panel shows: | Field | Description | |-------|-------------| | **Status** | Current state — *Active* (only enriching new records, refresh disabled), *Not Started*, *In Progress*, or *Waiting* (cycle completed, waiting for next refresh interval) | | **Cycle Progress** | Percentage of records processed in the current refresh cycle | | **Records Processed** | Number of records processed out of total matching records | | **Last Run** | When the last sync ran and how many records it processed | | **Estimated Runs Remaining** | Approximate number of syncs needed to complete the current cycle | #### Disabling Enrichment To stop enrichment for a specific record type, toggle it **off** in the enrichment configuration. This removes the enrichment rule, and no further syncs will process that record type. To temporarily pause enrichment without removing the configuration, set **Update records that already have enrichment data** to **Never** — this will only enrich new records with empty fields and skip all previously enriched records. ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the HubSpot CRM API directly. > **Org-level only**: HubSpot tools use the org-level integration credentials. **Contacts** | Tool | Description | |------|-------------| | `hubspot_list_contacts` | List contacts with pagination | | `hubspot_get_contact` | Get a contact by ID | | `hubspot_create_contact` | Create a new contact | | `hubspot_update_contact` | Update contact properties | **Companies** | Tool | Description | |------|-------------| | `hubspot_list_companies` | List companies with pagination | | `hubspot_get_company` | Get a company by ID | | `hubspot_create_company` | Create a new company | | `hubspot_update_company` | Update company properties | **Deals** | Tool | Description | |------|-------------| | `hubspot_list_deals` | List deals with pagination | | `hubspot_get_deal` | Get a deal by ID | | `hubspot_create_deal` | Create a new deal | | `hubspot_update_deal` | Update deal properties | **Search & Associations** | Tool | Description | |------|-------------| | `hubspot_search` | Search any CRM object type with filters | | `hubspot_get_associations` | Get associations between CRM objects | ## Delete Integration To delete the integration, simply click the 🗑️ button in the "Integrations" HubSpot card. We will remove any credentials in our system. You can also stop the integration by uninstalling the Suger App in your HubSpot account settings. --- Source: https://doc.fours.com/integrations/ # Integrations Fours connects to the external services your team already runs — your CRM, the cloud partner portals, your billing stack, your warehouse, your chat tool — so they stay in step with your marketplace business. This section is a lookup: find the service you need below, open its page, and follow the credential and permission steps for that provider. :::info Integrations have been moved to the Settings page. You can access and manage all integration services in [Fours Integrations](https://console.suger.io/settings?tab=integrations). ::: Once a service is connected, it becomes available to your Fours workflows and to the Fours AI agent. Most connectors are **org-level** — one shared API key, OAuth app, or service account for the whole organization. Others are **user-level**, where each person authenticates with their own account, and a few (Atlassian, ClickUp, Mailchimp, Monday, Google Calendar) are user-level only. Every page states which applies under **Org-Level vs User-Level**, then walks through prerequisites, authentication, and how to edit or delete the connection. If no purpose-built connector exists for a service you use, the generic OAuth 2.0 and MCP connectors under **Control sign-in and connect anything else** cover most of the gap. ## Find your integration ### Sync your CRM and sales data | Integration | What you use it for | | --- | --- | | [Salesforce](/integrations/salesforce/) | Create private offers, manage contracts, and co-sell across AWS, Azure, and GCP from inside your CRM. | | [HubSpot](/integrations/hubspot/) | Bi-directional referral sync between HubSpot deals and cloud partner programs such as AWS ACE, plus a Referral State deal property that records which cloud partners each deal has been shared with. | | [Microsoft Dynamics 365](/integrations/microsoft-dynamics365/) | Sync sales, customer, and operational data between Dynamics 365 and Fours. | | [Apollo](/integrations/apollo/) | Find verified contact information and enrich CRM records for outbound prospecting. | | [People Data Labs](/integrations/people-data-labs/) | Enrich leads and accounts with professional profile, employment history, and company data. | | [Gong](/integrations/gong/) | Bring call and meeting conversation intelligence into how you track deal progression. | ### Run co-sell with the cloud providers | Integration | What you use it for | | --- | --- | | [AWS Partner Central API](/integrations/aws-partner-network-api/) | The current AWS connection — sync opportunities, share referrals, and manage ACE co-sell engagements. | | [Azure Co-Sell](/integrations/azure-cosell/) | Co-sell with Microsoft sales teams through the Microsoft AI Cloud Partner Program. | | [GCP Co-Sell](/integrations/gcp-cosell/) | Sync co-selling opportunities and referrals with Google through the Google Cloud Partner Network. | | [Legacy Partner Central S3 Integration](/integrations/aws-partner-network-s3/) | Reference for the **deprecated** S3-based AWS connection. AWS has not provisioned it for new users since 2024, so new S3 connections cannot be created; existing ones still run. | | [AWS ACE Migration: S3 to Partner Central API](/integrations/aws-ace-migration-from-s3-to-api/) | The migration guide off that legacy S3 connection — update the IAM role, upgrade in the console, then re-run inbound and outbound sync. | ### Bill, meter, and close the books | Integration | What you use it for | | --- | --- | | [Lago](/integrations/lago/) | Forward usage metered in Lago to every connected cloud marketplace. | | [Metronome](/integrations/metronome/) | Forward usage metered in Metronome to every connected cloud marketplace. | | [Orb](/integrations/orb/) | Forward usage metered in Orb to every connected cloud marketplace. | | [Stripe](/integrations/stripe/) | Automate customer, coupon, and payment operations; a restricted key scopes access to marketplace work. | | [Chargebee](/integrations/chargebee/) | Report the metered overage Chargebee prices to your buyers' cloud marketplace bills every hour, and automate subscription operations. | | [Zuora](/integrations/zuora/) | Manage billing, subscription, and revenue data held in Zuora. | | [QuickBooks](/integrations/quickbooks/) | Send marketplace billing straight into your QuickBooks Online accounting ledger. | | [NetSuite](/integrations/netsuite/) | Connect the NetSuite ERP for finance, CRM, e-commerce, and supply-chain data. | | [Avalara](/integrations/avalara/) | Calculate sales, use, and VAT tax on invoices and sales orders, and validate customer addresses. | | [AWS Billing](/integrations/aws-billing/) | Sync AWS billing data for consolidated cloud cost management and reporting. | ### Analyze data and monitor your systems | Integration | What you use it for | | --- | --- | | [BigQuery](/integrations/bigquery/) | Query and manage data held in your Google BigQuery warehouse. | | [Snowflake](/integrations/snowflake/) | Execute SQL queries and insert or update rows in Snowflake. | | [Databricks](/integrations/databricks/) | Execute SQL queries, upload data files, and trigger jobs defined in Databricks. | | [PostHog](/integrations/posthog/) | Pull product-analytics events, insights, and cohorts, and inspect feature flags and experiments. | | [Datadog](/integrations/datadog/) | Verify your Datadog account and provision or disable Datadog users as part of operations workflows. | ### Notify people and send documents | Integration | What you use it for | | --- | --- | | [Slack](/integrations/slack/) | Receive Fours notifications and alerts in your Slack workspace, and chat with Fours AI there by direct message or @mention. Also connectable per user, so Fours AI posts **as you** rather than as the Suger bot. | | [Microsoft Teams](/integrations/microsoft-teams/) | Receive the same Fours notifications and alerts in your Teams channels. | | [Google Mail](/integrations/google-mail/) | Send, receive, and manage email through a connected Gmail account. Org-wide, connect either with a service account (send only) or with Sign in with Google (send and read). Connected per user, it also sends the co-sell and commission emails you trigger from your own mailbox. | | [Microsoft Outlook](/integrations/microsoft-outlook/) | Send, receive, and manage email through a connected Outlook account. | | [DNS Email](/integrations/dns-email/) | Send workflow and notification email from your own verified domain instead of `noreply@suger.io`. | | [DocuSign](/integrations/docusign/) | Automate agreement signing and track signature status on your contracts. | | [Mailchimp](/integrations/mailchimp/) | Sync audiences, manage contacts and tags, and launch or schedule marketing campaigns. | ### Support customers and run back-office operations | Integration | What you use it for | | --- | --- | | [Intercom](/integrations/intercom/) | Work your support queue — read, reply to, and triage conversations, and manage contacts, companies, and help-centre articles. | | [ServiceNow](/integrations/servicenow/) | Read and act on ITSM records: incidents, problems, change requests, approvals, and the service catalog. | | [Ironclad](/integrations/ironclad/) | Drive contract workflows end to end — approvals, signatures, documents — and search the records repository. | | [Workday](/integrations/workday/) | Read worker, organization, job-requisition, and time-off data, and submit time-off requests. | | [Lever](/integrations/lever/) | Manage the hiring pipeline — opportunities, postings, requisitions, interviews, and feedback. | | [Ashby](/integrations/ashby/) | Manage candidates, applications, interviews, and job postings in your recruiting pipeline. | ### Control sign-in and connect anything else | Integration | What you use it for | | --- | --- | | [Okta SSO](/integrations/okta-sso/) | OIDC single sign-on plus SCIM provisioning — create, update, and deactivate Fours users from Okta. | | [Google Workspace SSO](/integrations/google-workspace-sso/) | Single sign-on with Google Workspace, plus Directory Sync — three Google groups decide who is in your organization and with which role. | | [Auth0](/integrations/auth0/) | Single sign-on for your Fours organization using your existing Auth0 configuration. | | [OAuth 2.0](/integrations/oauth2-integration/) | Connect any service that speaks standard OAuth 2.0 when no purpose-built connector exists. | | [MCP (Model Context Protocol)](/integrations/mcp/) | Point Fours AI at an external MCP server so it can use that server's tools. This is the reverse of the [Fours MCP Server](/mcp/), which points *your* AI assistant at Fours. | ### Run AI features on your own model keys Bring your own key (BYOK): supply a provider API key and Fours' AI features run against your account with that provider. Read [What is metered](/insulin/billing/metering/) first — BYOK changes who charges you for the tokens, but Fours still charges a flat per-unit fee, and a zero credit balance still pauses AI requests. | Integration | What you use it for | | --- | --- | | [Anthropic](/integrations/anthropic/) | Your own Anthropic API key, so AI features run at Anthropic's cost rather than Fours'. | | [OpenAI](/integrations/openai/) | Your own OpenAI API key, so AI features run at OpenAI's cost rather than Fours'. | | [Google Gemini](/integrations/google-gemini/) | Your own Gemini API key, with the API usage billed to you directly by Google. | | [OpenRouter](/integrations/openrouter/) | Your OpenRouter key, for the models OpenRouter serves. | | [Together AI](/integrations/together/) | Your Together AI key, for the models Together serves. | | [Fireworks AI](/integrations/fireworks/) | Your Fireworks AI key, for the models Fireworks serves. | | [Baseten](/integrations/baseten/) | Your Baseten key, for the models you have deployed on Baseten. | | [DeepInfra](/integrations/deepinfra-byok/) | Your DeepInfra key, for the models DeepInfra serves. | | [Cloudflare Workers AI](/integrations/cloudflare/) | Your Workers AI API token and account ID, for the fixed set of Workers AI chat models Fours supports. | | [DigitalOcean GradientAI](/integrations/digitalocean/) | Your DigitalOcean model access key, for the fixed set of GradientAI chat models Fours supports. | ### Manage work, code, and files | Integration | What you use it for | | --- | --- | | [Asana](/integrations/asana/) | Create and manage tasks, projects, and workspaces, and automate task workflows. | | [Atlassian](/integrations/atlassian/) | Create and update Jira issues and Confluence pages. Each person connects their own Atlassian account. | | [ClickUp](/integrations/clickup/) | Manage ClickUp tasks and workflows from Fours, per user. | | [Monday](/integrations/monday/) | Reach your boards, workspaces, and user-level Monday data from a workflow. | | [Notion](/integrations/notion/) | Read and manage Notion pages, databases, and blocks. | | [GitHub](/integrations/github/) | Track repository activity and correlate development data with sales operations. | | [GitLab](/integrations/gitlab/) | Read and write repository files, branches, issues, and merge requests, and drive CI/CD pipelines — self-managed instances included. | | [Google Drive](/integrations/google-drive/) | Create, delete, update, and share files and folders in Drive. | | [Dropbox](/integrations/dropbox/) | Reach team files and member data in your Dropbox Business account. | | [Google Cloud Storage](/integrations/google-cloud-storage/) | List buckets, browse objects, and read file contents and object metadata. | | [Google Calendar](/integrations/google-calendar/) | Create events, manage schedules, and send invites from a workflow. User-level only — each person connects their own calendar. | ## Salesforce managed package The Suger Connector — the managed package that puts Fours objects, page components, and quick actions inside Salesforce — is versioned and installed separately from the CRM integration above. See [Install the Salesforce App](/salesforce-app/salesforce-app-install/) for the install and upgrade path, and [Salesforce App](/salesforce-app/) for what the package adds to your org. ## Connection health An org-level integration card shows more than whether a connection record exists. Each time you open **Settings → Integrations**, Fours re-checks the stored credential against the provider instead of trusting the fact that you connected once. A credential that was revoked, rotated, or deleted on the provider's side is caught here — rather than at the moment a workflow or an agent run needs it. Integrations you connect with an API key are the exception. For those, the check confirms that the stored key is still in place, but it does not ask the provider whether the key still works — so a key revoked or rotated on the provider's side is not caught here. Replace it as described below. When the stored credential no longer works, the card says so directly: > Connected, but this integration's stored credential can no longer be used — agents and workflows cannot reach it. Disconnect and connect it again to restore access. **Reconnecting is the fix.** Open the card's **⋯** menu, choose **Details**, and click **Reconnect** — or disconnect the integration and connect it again using the steps on its page. Nothing repairs the stored credential itself, and a connection in this state is not partially working — agents and workflows cannot reach the provider through it at all. :::info The check runs alongside the list on a short budget, so it never holds the **Integrations** page open. A card showing plain **Connected** either passed the check or could not be checked in time; both are treated as healthy, and the next time you open the page the result is there. Only the message above means action is required. ::: ## Scope and limits :::info Read each integration's **Org-Level vs User-Level** note before you connect. An org-level connection is shared by everyone in your organization; a user-level one works only for the person who authorized it, and several services support one mode but not the other. The S3-based AWS Partner Central connection is deprecated and closed to new users. If you still run it, plan the move to the Partner Central API. ::: --- Source: https://doc.fours.com/integrations/intercom/ # Intercom Connect Intercom so Fours AI can work with your conversations, contacts, and help centre articles. --- ## Overview [Intercom](https://www.intercom.com) is a customer messaging and support platform covering live chat, a shared inbox, and a help centre. Connecting it lets the Fours AI agent read and act on your support workload — conversations, contacts, companies, and articles — from a Fours workflow or chat. ### Org-Level vs User-Level > **Org-Level**: Supported. One Intercom administrator authorizes Fours once, and the connection serves the whole organization. > > **User-Level**: Not applicable, and not merely absent. An Intercom access token carries the permissions declared by the *app*, applied across the whole workspace — not the role of the admin who authorized it. A per-user connection would return exactly the same data as the org connection, so Fours does not offer one. ### How the connection works One Intercom administrator authorizes Fours through Intercom's own consent screen. Fours holds and refreshes the resulting token, and every tool then runs across the whole workspace under the scopes declared on the app — not under that admin's role. ```d2 shape: sequence_diagram admin: "Your Intercom admin" suger: "Fours" intercom: "Intercom" agent: "Fours AI agent" admin -> suger: "Click Connect on Intercom" suger -> intercom: "Hand off to Intercom's authorize page" admin -> intercom: "Sign in and click Authorize" intercom -> suger: "Access token, carrying THIS admin's grant" { style.stroke-dash: 4 } agent -> suger: "Run an Intercom tool" suger -> intercom: "Workspace-wide call under the app's declared scopes" intercom -> agent: "Conversations, contacts, companies, articles" { style.stroke-dash: 4 } offboarded: "if that admin is deactivated in Intercom" { intercom -> suger: "The org-wide connection can stop working — someone must reconnect" { style.stroke-dash: 4 } } ``` :::info Do not paste an Intercom **Access Token** from your own workspace's developer settings. Those tokens are for private apps on the workspace that owns them; using one to reach a different workspace is against Intercom's terms of service. Always connect through the OAuth flow below. ::: ## Create Integration (Org-Level) ### Prerequisites - An Intercom workspace, and an account with permission to install apps on it. - Currently supported for **US-region** workspaces. If your workspace is hosted in the EU or Australia, contact Fours support before connecting. - The Fours **Admin** role — connecting, disconnecting, and running an integration's actions are all admin-only in Fours. ### Authenticate by OAuth 1. In the Fours console, open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) and click **Connect** on **Intercom**. 2. Fours redirects you to Intercom. Sign in if prompted. 3. Review the access Fours requests and click **Authorize**. 4. Intercom returns you to the Fours console and the integration shows as connected. Fours stores and refreshes the resulting token; you never handle it directly. :::warning The token is tied to the Intercom administrator who authorized it. If that person's Intercom account is deactivated, the connection stops working and someone else has to reconnect. For a long-lived integration, authorize with a dedicated Intercom admin account rather than an individual's. ::: ## Fours AI Tools When Intercom is connected, the Fours AI agent can work your support queue through Fours' built-in tools (42 actions). > **Org-level**: All tools run under the app's declared scopes across the whole workspace, so the agent can read any conversation regardless of who it is assigned to. | Capability | What the agent can do | |------------|-----------------------| | **Conversations** | Create, read, search, and list conversations; reply, send a message, close, snooze, or reopen one (e.g. `reply-to-conversation`, `snooze-conversation`, `search-conversations`) | | **Contacts** | Full create/read/update/delete on contacts, plus search and merge (e.g. `create-contact`, `merge-contacts`, `search-contacts`) | | **Companies** | Create, read, update, delete, and list companies, and attach or detach contacts (e.g. `attach-contact-to-company`, `list-company-contacts`) | | **Help centre** | Create, read, update, delete, and list articles, and list collections (e.g. `create-article`, `list-help-center-collections`) | | **Tags** | Create and list tags, and apply or remove them on contacts, companies, and conversations (e.g. `tag-conversation`, `untag-contacts`) | | **Notes** | Add and list notes on a contact (e.g. `create-note`, `list-notes`) | | **Admins** | Read and list workspace administrators (e.g. `get-admin`, `list-admins`) | :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration Editing is not supported. To reconnect under a different account or workspace, delete the integration and authorize again. ## Delete Integration Click the 🗑️ button next to **Intercom** in the **Integrations** list. Fours' authorization is revoked and the token destroyed. To fully remove Fours from the Intercom side, also uninstall it from the workspace's app list in Intercom. --- Source: https://doc.fours.com/integrations/ironclad/ # Ironclad Connect Ironclad so Fours AI can work with your contract workflows, records, and signatures. --- ## Overview [Ironclad](https://ironcladapp.com) is a contract lifecycle management platform covering workflow-driven contract creation, approvals, signature, and a searchable repository. Connecting it lets the Fours AI agent drive contract workflows and read your records repository from a Fours workflow or chat. ### Org-Level vs User-Level > **Org-Level**: Supported, using the OAuth 2.0 client-credentials grant against your own Ironclad environment. > > **User-Level**: Not currently available. Ironclad's OAuth client is registered inside your own account rather than centrally, so there is no single Fours app your users could sign in to. ### How the connection works The OAuth client is registered in **your** Ironclad environment, not centrally by Fours. Fours exchanges its client ID and secret for an access token against your environment and refreshes it as needed. Ironclad also requires an acting user on every request, which is why the connect form asks for one. ```d2 shape: sequence_diagram admin: "Your Fours admin" ironclad: "Your Ironclad environment" suger: "Fours" agent: "Fours AI agent" admin -> ironclad: "Register an OAuth client and grant it scopes" admin -> suger: "Client ID + Secret, environment, acting-user email" agent -> suger: "Run an Ironclad tool" suger -> ironclad: "client_credentials grant at https://{environment}.ironcladapp.com" ironclad -> suger: "Access token — Fours refreshes it" { style.stroke-dash: 4 } suger -> ironclad: "API call, made on behalf of the acting user" ironclad -> agent: "Result, bounded by the client scopes AND that user's permissions" { style.stroke-dash: 4 } ``` ## Create Integration (Org-Level) ### Prerequisites - An Ironclad account with API access. - Permission to register an OAuth client (**Company Settings → API**). - An Ironclad user whose identity Fours should act as. Ironclad requires an acting user on every API request, so this is not optional. - The Fours **Admin** role — connecting, disconnecting, and running an integration's actions are all admin-only in Fours. ### Authenticate by client credentials 1. In Ironclad, register a new OAuth client and grant it the scopes you want Fours to have. Ironclad's scopes are per resource and action — for example `public.workflows.createWorkflows` — so a missing scope makes the matching tool fail. See [Register an OAuth client](https://developer.ironcladapp.com/reference/register-oauth-client). 2. Copy the **Client ID** and **Client Secret**. 3. In the Fours console, open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) and click **Connect** on **Ironclad**. 4. Enter: - **Client ID** and **Client Secret** — from step 2. - **Environment** — `na1`, `demo`, or `eu1`, matching your Ironclad tenant. - **Acting user email** — the Ironclad user Fours makes requests on behalf of. 5. Save. :::warning **The acting user is fixed at connect time and applies to every request, for everyone in your organization.** Whatever that person can see and do in Ironclad is exactly what the Fours agent can see and do — so the choice either over-grants or under-grants unless it is deliberate. Use a **dedicated Ironclad integration user**, not a real employee's account: if that employee leaves or their permissions change, the integration silently changes behaviour or stops working. ::: ## Fours AI Tools When Ironclad is connected, the Fours AI agent can drive contract workflows through Fours' built-in tools (46 actions). > **Org-level**: Every tool runs as the **acting user** configured above, within the scopes granted to your OAuth client. A permission error means one or the other is too narrow. | Capability | What the agent can do | |------------|-----------------------| | **Workflows** | Create a workflow (synchronously or async), read it, and list workflows; update its attributes (e.g. `create-workflow`, `create-workflow-async`, `update-workflow-attributes`) | | **Workflow lifecycle** | Pause, resume, cancel, or revert a workflow to review (e.g. `pause-workflow`, `revert-to-review-workflow`) | | **Approvals** | List a workflow's approvals and approval requests, and record a decision (e.g. `list-workflow-approvals`, `update-approval-status`) | | **Signatures** | Send a signature request, check signing status, and list signatures (e.g. `send-signature-request`, `get-sign-status`) | | **Documents** | List and download the documents attached to a workflow (`list-workflow-documents`, `download-workflow-document`) | | **Comments & history** | Add and list workflow comments, and read participants and turn history (e.g. `create-workflow-comment`, `list-workflow-turn-history`) | | **Schemas** | Read and list workflow schemas, and list eligible assignees (e.g. `get-workflow-schema`, `list-eligible-assignees`) | | **Records** | Create, read, replace, rename, delete, and list repository records; read metadata, run a record action, and export to XLSX (e.g. `create-record`, `run-record-action`, `export-records-xlsx`) | | **Entities** | Create, read, update, delete, and list entities, and read relationship types (e.g. `create-entity`, `list-entity-relationship-types`) | | **Webhooks** | Create, read, update, delete, and list webhooks, and fetch the verification key (e.g. `create-webhook`, `get-webhook-verification-key`) | :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration Editing is not supported. To change the acting user, rotate the client secret, or switch environments, delete the integration and create it again. ## Delete Integration Click the 🗑️ button next to **Ironclad** in the **Integrations** list. The stored client pair is destroyed with the integration record. Revoke the OAuth client in Ironclad too if you want to cut access from that side. --- Source: https://doc.fours.com/integrations/lago/ # Lago Automate the usage metering from Lago to all cloud marketplaces. --- ## Overview If you're currently dependent on [Lago](https://www.getlago.com/) for your metering and billing services and are aiming to grow your presence in cloud marketplaces, Fours presents the perfect solution to bridge this transition. Through our no-code, fully automated integration, you can effortlessly measure usage within your existing Lago setup and allocate it to clients across various cloud marketplaces. This integration eliminates the necessity for migration or complex engineering work, ensuring a seamless and trouble-free process. ## Create Integration In your [Fours Console Integration](https://console.suger.io/settings?tab=integrations), you will see the **Lago** integration connection. Click the `Connect` button to create an integration with your Lago instance. This will open an dialog for you to input - **API Key**: The Lago API key can be found in the [Lago's console](https://app.getlago.com/developers). - **Billing Mode**: `AMOUNT_DAILY` or `AMOUNT_HOURLY`. Fours fetch the usage metering records by amount & report to cloud marketplace metering service by daily or hourly. - **Region**: The region of the Lago instance. The region is used to fetch the billable metrics from Lago. > Lago integration connection dialog in Fours Console Once the integration process is finished, you can proceed by clicking the `VERIFY` button. This action triggers the Fours service to test the connection to the APIs of your Lago instance. If everything is configured correctly, the integration status will be updated as `VERIFIED`. ## Edit Integration Editing an existing Lago integration is supported. Click the `Edit` button to open the dialog of editing Lago integration as shown below. - **Enable Auto Report Usage**. You can choose to enable or disable the automatic usage report feature for Lago. Enabling this feature allows Fours to run an hourly cron job to retrieve the daily/hourly aggregated subscription usages or costs from Lago and report them as UsageRecordGroups to the [Fours metering API](/metering/usage-metering/). On the other hand, disabling this feature means that no cron job will be scheduled for this purpose. - **Billing Mode**: `AMOUNT_DAILY` or `AMOUNT_HOURLY`. Fours fetch the billable metrics by amount daily or hourly. ## Delete Integration The Lago integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the API Key will be deleted immediately & permanently from Fours. No time window or methods to recover. ## Billing Mode There are two billing modes available for Fours-Lago integration: **AMOUNT_DAILY** and **AMOUNT_HOURLY**. The following instructions detail how to configure the source dimension keys in [metering dimension conversion](/metering/usage-metering/#metering-dimension-conversion) for each mode separately. 1. **AMOUNT_HOURLY**: Fours fetch & report the billable metrics by amount every one **HOUR**. Use the original Lago billable metrics as the source dimension keys in the configuration of [metering dimension conversion](/metering/usage-metering/#metering-dimension-conversion) 2. **AMOUNT_DAILY**: Fours fetch & report the billable metrics by amount every one **DAY**. Use the original Lago billable metrics as the source dimension keys in the configuration of [metering dimension conversion](/metering/usage-metering/#metering-dimension-conversion) :::tip - Fours fetches the billable metrics from Lago every one hour. If there is an increase in the billable metrics, Fours will generate a new usage record and report it to cloud marketplaces. However, if the billable metrics remain the same or decrease, Fours will refrain from creating new usage records. - In cases where coupons are granted to the customer in Lago, resulting in a potential decrease in the billable metrics, Fours retains a comprehensive history of billable metrics and monitors any changes. If the billable metrics decrease or remain unchanged, Fours will suspend the automatic fetching and reporting of usage until it surpasses the maximum value recorded in its history. ::: ## Connect Lago customer To enable Fours to fetch and report the billable metrics of Lago Customers to the appropriate entitlements in Cloud Marketplace, you need to connect the Buyer in Fours with the corresponding Customer in Lago. Simply click the `Edit` button in the Buyer and add the corresponding Lago Customer ID. This setup only needs to be done once; afterward, Fours' service will automatically retrieve the latest billable metrics and report them to the correct Cloud Marketplace entitlements. > Lago Customer ID field in the Buyer edit dialog --- Source: https://doc.fours.com/integrations/lever/ # Lever Connect Lever so Fours AI can work with your opportunities, postings, and interview feedback. --- ## Overview [Lever](https://www.lever.co) is a talent acquisition platform combining an applicant tracking system with CRM-style candidate nurturing. Connecting it lets the Fours AI agent read and update your hiring pipeline — opportunities, postings, requisitions, interviews, and feedback — from a Fours workflow or chat. ### Org-Level vs User-Level > **Org-Level**: Supported. One Lever API key serves the whole organization. > > **User-Level**: Not currently available. Lever does support OAuth, but issuing an OAuth client requires acceptance into [Lever's partner integration program](https://hire.lever.co/developer/oauth) — Lever's own team creates the app and sends the credentials after a sandbox build and a live review. Until that completes, Lever is org-only. ### How the connection works Lever authenticates with HTTP Basic, where the API key *is* the username and the password is empty. Fours stores the key and builds that header for you, so the connect form has a single field. ```d2 shape: sequence_diagram admin: "Your Fours admin" lever: "Lever" suger: "Fours" agent: "Fours AI agent" admin -> lever: "Generate an API key (Super Admin)" admin -> suger: "Paste it into the single User name field" suger -> suger: "Store the key; Fours supplies the empty password half" agent -> suger: "Run a Lever tool" suger -> lever: "HTTP Basic — the key as the username, blank password" lever -> agent: "Opportunities, postings, requisitions, feedback" { style.stroke-dash: 4 } ``` ## Create Integration (Org-Level) ### Prerequisites - A Lever account on a plan that includes API access. - **Super Admin** on that Lever account. The API credentials page is not visible to other roles. - The Fours **Admin** role — connecting, disconnecting, and running an integration's actions are all admin-only in Fours. ### Authenticate by API key 1. In Lever, go to [**Settings → Integrations and API**](https://hire.lever.co/settings/integrations) and open the **API credentials** tab. 2. Generate a new API key and copy it. See Lever's [Generating and using API credentials](https://help.lever.co/hc/en-us/articles/20087297592477-Generating-and-using-API-credentials) for the current walkthrough. 3. In the Fours console, open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) and click **Connect** on **Lever**. 4. Paste the key into **User name** and save. :::info The one field is labelled **User name** because Lever authenticates with HTTP Basic where the API key *is* the username. Paste the API key there. There is no separate username, and no password field — Fours supplies the empty password half itself. ::: ## Fours AI Tools When Lever is connected, the Fours AI agent can work your hiring pipeline through Fours' built-in tools (61 actions). > **Org-level**: All tools run under the org API key, so the agent's reach matches that key's permissions. | Capability | What the agent can do | |------------|-----------------------| | **Opportunities** | Create opportunities and move them through the pipeline — stage, archive state, tags, sources, and links (e.g. `create-opportunity`, `update-opportunity-stage`, `update-opportunity-archived`) | | **Candidate detail** | Read an opportunity's resumes, referrals, panels, file actions, and contact record (e.g. `get-opportunity-resumes`, `update-contact`) | | **Postings** | Read, list, and update job postings, apply to one, and read posting users (e.g. `get-postings`, `update-posting`, `apply-posting`) | | **Requisitions** | Full create/read/update/delete on requisitions, plus their configurable fields (e.g. `create-requisition`, `get-requisition-fields`) | | **Interviews & panels** | Create panels, and update or delete scheduled interviews (e.g. `create-panel`, `update-interview`) | | **Feedback** | Manage feedback forms and templates end to end (e.g. `create-feedback`, `update-feedback-template`) | | **Notes** | Add, read, and delete notes on a candidate (e.g. `create-note`, `delete-note`) | | **Users** | Create users, update them, and deactivate or reactivate accounts (e.g. `create-user`, `deactivate-user`) | | **Webhooks** | Create, list, and delete Lever webhooks (e.g. `create-webhook`, `get-webhooks`) | | **Reference data** | Read stages, archive reasons, disposition stages, sources, and tags (e.g. `get-stages`, `get-archive-reasons`) | | **Compliance** | Read EEO survey responses — anonymous (`get-eeo-responses`) or including personally identifiable information (`get-eeo-responses-pii`) | | **Deletion audit** | List records Lever has deleted — applications, opportunities, and postings (e.g. `get-opportunities-deleted`) | :::warning `get-eeo-responses-pii` returns EEO survey responses **including personally identifiable information**, where `get-eeo-responses` returns the anonymous set. Treat the first as regulated personal data, and only let an agent reach it when your own policy allows. ::: :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration Editing is not supported. To rotate the key or point Fours at a different Lever account, delete the integration and create it again. ## Delete Integration Click the 🗑️ button next to **Lever** in the **Integrations** list. The stored key is destroyed with the integration record, and any workflow or agent depending on Lever tools stops working immediately. Revoke the key in Lever too if you want to cut access from that side. --- Source: https://doc.fours.com/integrations/mailchimp/ # Mailchimp ## Overview Mailchimp is an email-marketing and audience-management platform for running campaigns, managing subscriber lists, and tracking engagement. Connect Mailchimp to Fours so the Fours AI agent can act on your marketing data — syncing audiences, managing contacts and tags, launching or scheduling campaigns, and pulling campaign performance reports — alongside your cloud-marketplace workflows. ### Org-Level vs User-Level > **User-Level Only**: Mailchimp is configured per user. Each user authenticates with their own Mailchimp account via OAuth. ## Create User Integration ### Authenticate 1. Navigate to Settings > Integrations > User Integrations 2. Click `Connect Now` in the Mailchimp section 3. You will be redirected to Mailchimp to authorize 4. Grant Fours access to your Mailchimp account 5. Return to Fours to confirm the connection :::note Each user connects their own Mailchimp account. Fours stores the OAuth credential securely and does not support manual credential entry for this integration. ::: ## Fours AI Tools When Mailchimp is connected, the Fours AI agent can work with your Mailchimp marketing data through Fours' built-in tools (34 actions). Capabilities are grouped below. > **User-level**: Tools run against the connected user's Mailchimp account. | Capability | What the agent can do | |------------|-----------------------| | **Audiences (lists)** | Create and manage subscriber lists (e.g. `create-audience`, `list-audiences`, `update-audience`) | | **Members & contacts** | Add, update, and tag list members (e.g. `create-member`, `update-member`, `tag-member`) | | **Campaigns** | Create, update, schedule, and send email campaigns (e.g. `create-campaign`, `schedule-campaign`, `list-campaigns`) | | **Segments & tags** | Build and filter audience segments for targeting (e.g. `create-segment`, `list-segments`) | | **Templates** | Manage reusable email templates (e.g. `create-template`, `list-templates`) | | **E-commerce stores** | Manage connected stores and sales data (e.g. `create-store`, `list-stores`) | | **Automations & reports** | Read automation workflows and campaign performance (e.g. `list-automations`, `get-campaign-report`) | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the stored Mailchimp credential from Fours and revokes Fours access to the connected account. :::warning Deleting the integration removes Fours access to Mailchimp immediately. Reconnect the integration if you need to restore access later. ::: --- Source: https://doc.fours.com/integrations/mcp/ # MCP (Model Context Protocol) Connect any MCP-compatible server to give Fours AI access to external tools and data. --- ## Overview The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is an open standard for connecting AI assistants to external tools and data sources. Fours' MCP integration lets you connect to **any MCP server** that supports OAuth 2.1 authorization, giving Fours AI the ability to use tools from 75+ popular services --- or any custom MCP server you provide. Once connected, Fours AI can discover and use all tools exposed by the MCP server. For example, connecting your Stripe MCP server lets Fours AI look up payments, manage subscriptions, and query billing data on your behalf. ### Org-Level vs User-Level > **Org-Level**: Not applicable. MCP server connections are user-level only. > > **User-Level**: Each user connects their own MCP servers with their personal credentials. Tools are available to that user's Fours AI sessions. ## Pre-Configured Providers Fours includes a catalog of 77 pre-configured MCP servers. Select any provider from the catalog to connect instantly --- no manual URL entry required. | # | Provider | Category | |---|----------|----------| | 1 | Ahrefs | Marketing | | 2 | Airtable | Productivity | | 3 | Apollo.io | Sales | | 4 | Asana | Project Management | | 5 | Atlassian (Jira/Confluence/Trello) | Developer Tools | | 6 | Box | File Storage | | 7 | Brevo | Marketing | | 8 | Calendly | Scheduling | | 9 | Canva | Design | | 10 | Circleback | Productivity | | 11 | Clay | Sales & Marketing | | 12 | Clerk | Developer Tools | | 13 | ClickUp | Project Management | | 14 | Close CRM | CRM | | 15 | Cloudflare | Infrastructure | | 16 | Cloudflare Developer Platform | Developer Tools | | 17 | Coda | Productivity | | 18 | Context7 | Developer Tools | | 19 | Crossbeam | Partnerships | | 20 | DevRev | Customer Support | | 21 | DocuSign | Legal | | 22 | Dropbox | File Storage | | 23 | Excalidraw | Design | | 24 | Fathom | Productivity | | 25 | Fellow | Productivity | | 26 | Figma | Design | | 27 | Fireflies | Productivity | | 28 | Gamma | Productivity | | 29 | Granola | Productivity | | 30 | Guru | Knowledge Management | | 31 | Honeycomb | Observability | | 32 | Hugging Face | Developer Tools | | 33 | incident.io | Incident Management | | 34 | Intercom | Customer Support | | 35 | Intuit Mailchimp | Marketing | | 36 | Intuit QuickBooks | Finance | | 37 | Klaviyo | Marketing | | 38 | Linear | Project Management | | 39 | Lucid | Design | | 40 | MailerLite | Marketing | | 41 | Make | Automation | | 42 | Mermaid Chart | Design | | 43 | Microsoft 365 | Productivity | | 44 | Miro | Design | | 45 | Mixpanel | Analytics | | 46 | Monday | Project Management | | 47 | Netlify | Developer Tools | | 48 | Notion | Productivity | | 49 | Otter.ai | Productivity | | 50 | Outreach | Sales | | 51 | PagerDuty | Incident Management | | 52 | PandaDoc | Legal | | 53 | PostHog | Analytics | | 54 | Postman | Developer Tools | | 55 | Pylon | Customer Support | | 56 | Ramp | Finance | | 57 | Razorpay | Payments | | 58 | Semrush | Marketing | | 59 | Sentry | Developer Tools | | 60 | Shopify | E-commerce | | 61 | Slack | Communication | | 62 | Smartsheet | Project Management | | 63 | Stripe | Payments | | 64 | Supabase | Developer Tools | | 65 | Superhuman Mail | Communication | | 66 | Supermetrics | Analytics | | 67 | Todoist | Productivity | | 68 | Twilio | Communication | | 69 | Typeform | Productivity | | 70 | Vercel | Developer Tools | | 71 | Webflow | Developer Tools | | 72 | Wix | Productivity | | 73 | WordPress.com | Productivity | | 74 | Wrike | Project Management | | 75 | Zapier | Automation | | 76 | Zoom | Communication | | 77 | ZoomInfo | Sales | You can also connect **any custom MCP server** by entering its URL directly. ## Authentication Methods Fours connects to MCP servers with **OAuth (PKCE)** only. You sign in and approve access on the server's own authorization page; Fours discovers the server's OAuth configuration, registers itself as a client, and refreshes the token for you (see [How It Works](#how-it-works)). The server must support OAuth 2.1, so a server that offers only client credentials or a static API key can't be connected. ```d2 shape: sequence_diagram you: "You" fours: "Fours" server: "MCP server" auth: "Its authorization server" you -> fours: "Add MCP server: + on a catalog card, or a URL and Connect" fours -> server: "Which authorization server protects you?" fours -> auth: "Get its endpoints; register Fours as a client" fours -> you: "Authorization page, in a new tab" { style.stroke-dash: 4 } you -> auth: "Log in and approve access" auth -> fours: "Authorization code, exchanged with PKCE for tokens" { style.stroke-dash: 4 } fours -> you: "MCP server connected successfully" { style.stroke-dash: 4 } fours -> server: "Fours AI calls the server's tools with the token" ``` ## Create Integration ### Connect via Catalog (OAuth) 1. Navigate to **Settings > Integrations** and scroll to **Custom MCP Servers** 2. Click **Add MCP server** 3. Under **Popular MCP Servers**, find the provider (e.g., Stripe, Linear, Notion) — search, or filter by category — and click **+** on its card. A provider with more than one endpoint lets you pick one on the card first 4. The provider's authorization page opens in a new tab 5. Log in and approve access 6. Back in Fours, the dialog closes with *MCP server connected successfully*, and the server appears under **Custom MCP Servers** ### Connect via Custom URL (OAuth) 1. Navigate to **Settings > Integrations**, scroll to **Custom MCP Servers**, and click **Add MCP server** 2. Enter your MCP server URL (e.g., `https://mcp.example.com/mcp`) in **Remote MCP Server URL** and click **Connect** 3. Fours automatically discovers the server's OAuth configuration and opens its authorization page in a new tab 4. Follow the OAuth authorization flow 5. When it completes, the server appears under **Custom MCP Servers** ### Connect Fours' own MCP server The catalog also lists Fours' own MCP server — the one described in the [MCP](/mcp/) section — on a card the console still labels **Suger**. Connecting it gives your Fours AI sessions the Fours tools, and on this card you also choose how much of the server those sessions may use. 1. Navigate to **Settings > Integrations** and scroll to **Custom MCP Servers**. 2. Click **Add MCP server**. 3. In **Connect a custom MCP server**, find the **Suger** card (server `https://apiv2.suger.cloud/mcp`, category **Marketplace**). 4. Pick an **Access** level on the card, then click **+** and complete the authorization in the window that opens. That window is the Fours console sign-in. If your organization signs in with single sign-on and the window stops before the **Authorize Application** screen — for example, on an error page — see [Troubleshooting](/mcp/setup/#troubleshooting) in the MCP setup guide. | Access | Tools your Fours AI sessions get | |--------|----------------------------------| | **Read only** (default) | Only tools that read data | | **Read & write** | Read tools, plus every tool that creates or changes data — except deletes | | **Read, write & delete** | Every tool, including the ones that delete records | - Once connected, the card shows the level you chose — for example **Access: Read only**. To change it, disconnect the server and connect it again with the level you want. - A connection made before the **Access** choice existed counts as **Read only**, so it gets no write tools until you reconnect it with wider access. - **Access** only narrows the tools on offer. It never widens what your Fours account may do: Fours still checks your permissions on every call. - Only this card has an **Access** choice; other MCP servers expose whatever tools they offer. For what each tool does, see [Supported Tools](/mcp/tools/). ### Verification There is no separate **Verify** step: a server counts as connected once its authorization completes, and Fours AI can use its tools from then on. If the authorization doesn't finish within five minutes, the dialog stops waiting and says the connection timed out — try again. A server whose connection didn't complete shows a **Delete** button instead of its **⋯** menu; delete it and add the server again. ## Edit Integration Editing is not supported. To connect a different account — or, for Fours' own server, a different **Access** level — disconnect the server and add it again. ## Delete Integration To remove a server, open its **⋯** menu under **Custom MCP Servers** and choose **Disconnect**. This removes the connection and its stored credentials from Fours. :::warning This does not revoke access on the provider side. Visit the provider's app settings to revoke Fours' access. ::: ## How It Works ### OAuth Discovery For OAuth-based connections, Fours automatically discovers the provider's authorization endpoints using open standards: 1. **RFC 9728** (Protected Resource Metadata) --- determines which authorization server protects the MCP endpoint 2. **RFC 8414** (Authorization Server Metadata) --- retrieves the authorization, token, and registration endpoints 3. **RFC 7591** (Dynamic Client Registration) --- registers Fours as an OAuth client if no pre-registered app exists This means most MCP servers work out of the box without any manual endpoint configuration. ### Token Refresh Tokens are refreshed automatically before expiry using the refresh token. If no refresh token was issued, you must reconnect when the token expires. ### One Connection Per Provider Each user can have one MCP connection per provider. To switch accounts or credentials, disconnect the existing integration first, then reconnect. ## Fours AI Tools MCP integrations do not provide a fixed set of AI tools. Instead, when you connect an MCP server, Fours AI automatically discovers **all tools** that the server exposes. The available tools depend entirely on the provider. For example: - **Stripe MCP** might expose tools for querying payments, managing customers, and creating invoices - **Linear MCP** might expose tools for creating issues, updating projects, and searching tickets - **Notion MCP** might expose tools for reading pages, creating databases, and searching content Fours AI asks the server for its current tools each time it starts work, so the list follows whatever the provider's MCP server offers and changes as the provider updates it. --- Source: https://doc.fours.com/integrations/metronome/ # Metronome Automate the usage metering from Metronome to all cloud marketplaces. --- ## Overview If you currently rely on [Metronome](https://metronome.com/) as your metering/billing service and are looking to expand your business in cloud marketplaces, Fours offers the ideal solution to bridge the gap. With our no-code, fully automated integration, you can seamlessly meter usages from your existing Metronome instance to clients in all cloud marketplaces. There is no need for migration or extensive engineering efforts, making the process smooth and hassle-free. :::warning This integration does not currently disambiguate between a buyer's [AWS Concurrent Agreements](/aws-marketplace/integration/#enable-concurrent-agreements) for the same product — usage can be attributed to the wrong agreement. If your product has Concurrent Agreements enabled, report usage through Fours directly instead. See [Usage Metering for AWS Concurrent Agreements](/metering/usage-metering/#usage-metering-for-aws-concurrent-agreements). ::: ### Org-Level vs User-Level > **Org-Level Only**: Metronome integration is available at the organization level only. All users in the organization share the same Metronome connection for usage metering. When it comes to adopting Fours with Metronome together, you have two options available. However, we highly recommend **Option 2**, and here's why: | | Option 1 | Option 2 (recommend) | | ----------- | ----------- | ------------ | | Architecture |
Direct Metronome to AWS Marketplace integration architecture diagram | Integration architecture diagram: the ISV / Seller connects to Metronome, Metronome to Suger, and Suger to the AWS, Azure, and Google Cloud marketplaces | | Description | Metronome offers officially integrating with AWS Marketplace and sends usage metering to AWS Marketplace metering service directly. Here is the [official guidance](https://docs.metronome.com/integrations/marketplace-integrations/aws). | Fours provides pre-built integration to connect Metronome & cloud marketplaces. Hourly cron jobs automatically fetch aggregated usage events and report them to cloud marketplace in the right formats. | | :white_check_mark: Pros |
  • Officially supported by Metronome.
|
  • Support all cloud marketplaces (AWS, Azure & GCP).
  • No manual work in Metronome to support private offer in cloud marketplace.
  • Support usage metering verification to avoid overcharge or undercharge.
  • Fully support AutoRenew, Manual Renew / Upsell, Change Plan.
  • Easy configuration, no-code & engineering-free.
| | :no_entry_sign: Cons |
  • Only AWS Marketplace, GCP or Azure is not supported
  • Require mannual creation of plan & credit in Metronome for each private offer in cloud marketplace.
  • No usage metering verification
  • No support AutoRenew, Manual Renew / Upsell, Change Plan
  • Non-trivial configuration & setup
|
  • Up to 2 hours delay of reporting usage events to cloud marketplaces
| ## How the sync works | | | | --- | --- | | **Direction** | One-way: Metronome → Fours → cloud marketplace. Fours reads usage and invoices from Metronome and reports them onward as [usage record groups](/metering/usage-metering/). Fours never writes back to Metronome. | | **Source of truth** | Metronome owns usage and invoice amounts. Fours owns the mapping to marketplace dimensions and the reported records. | | **Scope** | Organization-level only — one Metronome connection per Fours organization, shared by all users. | | **Schedule** | An hourly job at **35 minutes past the hour**, when **Enable Auto Report Usage** is on and the integration is `VERIFIED`. In `amount_daily` billing mode the amount is reported daily rather than hourly. | | **Credentials** | A Metronome API token, sent as a bearer token. Fours stores it in a secret manager, not in the integration record, and deleting the integration deletes it immediately and permanently. Give the token access to the invoice and usage endpoints Fours reads — Metronome's [authentication guide](https://docs.metronome.com/api-reference/authentication) covers issuing one. | ### When something fails - **One bad buyer or invoice does not stop the run.** The sync logs the failure and continues to the next buyer and the next invoice, so a single unmappable record cannot block every other customer's usage for that hour. - **Transient failures are retried automatically** — the per-organization sync retries after a 10-second delay, and the run has a 60-minute ceiling. - **A failed hour is not skipped forever.** The job re-reads current usage and invoice state on its next pass, so a recovered outage catches up on the following run rather than needing a manual backfill. - **Duplicate reporting is guarded by amount history, not by retry count.** In `amount_hourly` and `amount_daily` modes Fours tracks the highest invoice total it has already reported per Metronome invoice ID and only reports increases — so a retried or repeated run does not double-charge. ## Create Integration In your [Fours Console Integration](https://console.suger.io/settings?tab=integrations), you will see the Metronome integration connection. Click the `Connect` button to create an integration with your Metronome instance. This will open an dialog for you to input - **API Token**: The [Metronome API token](https://docs.metronome.com/api-reference/authentication). - **Billing Mode**: Select one of `quantity`, `amount_hourly` or `amount_daily`. See [Billing Mode](#billing-mode) for the difference between them. > Metronome integration dialog with API Token and Billing Mode fields Once the integration process is finished, you can proceed by clicking the `VERIFY` button. This action triggers the Fours service to test the connection to the APIs of your Metronome instance. If everything is configured correctly, the integration status will be updated as `VERIFIED`. ## Edit Integration Editing an existing Metronome integration is supported. Click the `Edit` button to open the dialog of editing Metronome integration as shown below. - **Enable Auto Report Usage**. You can choose to enable or disable the automatic usage report feature for Metronome. Enabling this feature allows Fours to run an hourly cron job to retrieve the aggregated usage events from Metronome and report them as UsageRecordGroups to the [Fours metering API](/metering/usage-metering/). On the other hand, disabling this feature means that no cron job will be scheduled for this purpose. - **Billing Mode**: `quantity`, `amount_hourly` or `amount_daily`. See [Billing Mode](#billing-mode) for the difference between them. Following features are available when the billing mode is `amount_hourly` or `amount_daily`: - **Enable Report Finalized Invoice Only**: If enabled, Fours will only report finalized invoices to cloud marketplaces. By default, Fours will also report draft invoices to cloud marketplaces. - **Enable Invoice End Date Check**: If enabled, Fours will check the `end date` of the invoice. If the `end date` is not in the entitlement time window, Fours will not report the usage to cloud marketplaces. - **Enable Auto Credit Back for Voided Invoices**: If enabled, Fours will automatically add reported amount of voided invoices to the entitlement as credit. By default, Fours will not add the voided invoices to the entitlement as credit. - **Enable Invoice Filter**: If enabled, a JavaScript filter you supply decides which invoices Fours ingests. Leave it off to ingest every invoice that passes the other checks above. - **Invoice Filter Code**: Applicable only when **Enable Invoice Filter** is on. Your code receives `$invoices` (the array of invoice objects fetched from Metronome) and must set `$target.invoiceIds` to the IDs it wants to keep. For example, to ingest only invoices a Metronome custom field has not opted out: ```javascript const invoiceIds = []; for (const invoice of $invoices) { if (invoice.custom_fields && invoice.custom_fields.suger_ingest_invoice !== 'false') { invoiceIds.push(invoice.id); } } $target.invoiceIds = invoiceIds; ``` - **Allow Zero Usage Record Group**. By default Fours skips creating a usage record group when a sync produces no usage. Enable this to create the zero-record group anyway — it is still not reported to the cloud marketplace, but it makes "we synced and there was genuinely no usage" distinguishable from "the sync did not run". > ![Metronome Integration Amount Options](images/metronome_integration_amount_options.jpg) :::warning - Fours only sync invoices with billing periods that **begin on or after the first day of the previous month**. Any billing periods that start before this date will not be reported to cloud marketplaces. - If the **start date** of the invoice is in the future, Fours will not report the usage to cloud marketplaces. - **Enable Billable Metric Whitelist**. If enabled, only the billable metrics in the whitelist will be metered & reported from Metronome to cloud marketplaces. Otherwise all the metrics listed in the `Billable Metric Full List` will be metered & reported to cloud marketplaces. - **Billable Metric Whitelist**. Applicable only when the `Enable Billable Metric Whitelist` is true. - **Billable Metric Full List**. Every non-archived billable metric in your Metronome account. It is auto fetched from Metronome, not editable. :::warning - If the billing mode is `quantity`, please ensure all billable metrics in the `Whitelist` (if the whitelist is enabled) or the `Full List` (if the whitelist is not enabled) have been mapped to their respective cloud marketplace dimensions in the [Metering Dimension Conversion](/metering/usage-metering/#metering-dimension-conversion). - Metronome Auto Fetch & Report Job: In case any billable metrics from Metronome cannot be successfully converted to metering dimensions in the cloud marketplace, it may result in the entire Metronome auto fetch and report job failing. - If you notice any discrepancies or missing usage reporting, please verify whether this is caused by incomplete mapping of billable metrics to cloud marketplace dimensions. If so, rectify the mapping accordingly to ensure accurate reporting. ::: > Edit Metronome integration dialog with billing and metric options ## Delete Integration The Metronome integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the API token will be deleted immediately & permanently from Fours. No time window or methods to recover. ## Billing Mode There are three billing modes available for Fours-Metronome integration: **quantity**, **amount_hourly** or **amount_daily**. 1. **quantity**: Fours fetch & report the billable metrics by quantity every one **HOUR**. Use the original Metronome billable metrics as the source dimension keys in the configuration of [metering dimension conversion](/metering/usage-metering/#metering-dimension-conversion) 2. **amount_hourly**: Fours fetch & report `invoice total amount` every one **HOUR**. The `invoice total amount` is converted to the dimension `metronome` with fixed unit price as **$1**. Use `metronome` as the only source dimension key in the configuration of [metering dimension conversion](/metering/usage-metering/#metering-dimension-conversion). :::tip - Fours fetches [Metronome Invoice API](https://docs.metronome.com/api/#operation/listInvoices) every one hour. If there is an increase in the `invoice total amount`, Fours will generate a new usage record and report it to cloud marketplaces. However, if the `invoice total amount` remains the same or decreases, Fours will refrain from creating new usage records.. - In cases where credits are granted to the customer in Metronome, resulting in a potential decrease in the `invoice total amount`, Fours retains a comprehensive history of invoice total amounts and monitors any changes. If the `invoice total amount` decreases or remains unchanged, Fours will suspend the automatic fetching and reporting of usage until it surpasses the maximum value recorded in its history. ::: 3. **amount_daily**: Fours fetch & report the `invoice total amount` every one **DAY**. The total amount is converted to the dimension `metronome` with fixed unit price as **$1**. Use `metronome` as the only source dimension key in the configuration of [metering dimension conversion](/metering/usage-metering/#metering-dimension-conversion). :::warning When using the `amount_hourly` or `amount_daily` billing modes, pay attentions to the following: - Fours tracks each invoice amount using the Metronome `invoice ID` and reports increases to the cloud marketplace on an hourly or daily basis. If a customer’s contract is modified or an operation changes the `invoice ID`, Fours will start reporting amounts based on the new invoice ID. This can lead to a sudden spike in the usage report. - To avoid this, **schedule contract changes or similar operations to take effect at the beginning of the month**. This approach minimizes disruptions and ensures a smoother and more consistent usage reporting process. ::: --- Source: https://doc.fours.com/integrations/microsoft-dynamics365/ # Microsoft Dynamics 365 Microsoft Dynamics 365 is a cloud-based business applications platform that combines CRM and ERP capabilities. Integrate with Dynamics 365 to sync sales, customer, and operational data with Fours. --- ## Overview ### Org-Level vs User-Level There are **two separate configurations**, and they authenticate in different ways: | | **Org-Level** | **User-Level** | |---|---|---| | **Auth flow** | Azure AD **client credentials** (app-only) | OAuth 2.0 **authorization code** (delegated) | | **Acts as** | The application user you create in Dynamics 365 — not a person | The signed-in person | | **Sees** | Whatever the application user's security roles allow, across the organization | Only the Dynamics 365 data that person can already see | | **Best for** | Backend integrations, scheduled syncs, and automated workflows | Individual users working with their own records | **Both** configurations require you to supply two values before the connection can start: - **Tenant ID** — your Azure AD (Microsoft Entra ID) directory ID. - **Instance URL** — your Dynamics 365 environment, e.g. `https://{your-org}.crm.dynamics.com`. These cannot be discovered automatically, so the connect flow shows a short **pre-start form** asking for them before it hands you off to Microsoft. They are used to build the correct authority and API endpoints for your environment, and are validated against the same schema on both levels. ![The Connect Microsoft Dynamics 365 dialog — Fours opens a secure connect session, then shows the Microsoft authorization step](images/dynamics365-connect.png) :::tip Find your **Tenant ID** in the Azure portal under **Microsoft Entra ID → Overview**. Find your **Instance URL** in the Power Platform Admin Center under **Environments** — it is the environment URL, and Fours expects the bare `*.crm.dynamics.com` host without an API path appended. ::: ### How the connection works Both levels talk to the same Dataverse Web API on your environment; only *who* the calls act as differs. The org connection acts as the application user you create in Dynamics 365, so its reach is exactly what that user's security roles allow. A user connection acts as the signed-in person, so it can never see or change more than that person already could in Dynamics 365. Reads and writes both go over this one path — a write is an ordinary Dataverse create or update, and Fours asks Dataverse to echo the stored record back so you see what actually landed rather than what was sent. ```d2 shape: sequence_diagram admin: "Your Fours admin" person: "An individual Fours user" microsoft: "Microsoft Entra ID" dataverse: "Your Dynamics 365 environment" suger: "Fours" org: "Org-level — app-only" { admin -> suger: "Tenant ID + Instance URL" suger -> microsoft: "Client credentials for the application user" microsoft -> suger: "Token scoped to your environment" { style.stroke-dash: 4 } } user: "User-level — delegated" { person -> suger: "Tenant ID + Instance URL" suger -> microsoft: "Authorization code sign-in" microsoft -> suger: "Token acting as that person" { style.stroke-dash: 4 } } read: "Read" { suger -> dataverse: "Query records, get a record, confirm who the connection acts as" dataverse -> suger: "Records the connection is allowed to see" { style.stroke-dash: 4 } } write: "Write" { suger -> dataverse: "Create or update a record" dataverse -> suger: "The record as Dataverse stored it, plus its id" { style.stroke-dash: 4 } } ``` --- ## Create Integration (Org-Level) Org-level integration uses Azure AD client credentials for application-level access. This is suitable for backend integrations that need to access data across the organization. ### Prerequisites - Dynamics 365 instance URL (e.g., `https://yourorg.crm.dynamics.com`) - Tenant ID from Azure AD - **Application User in Dynamics 365**: Create an [application user](https://learn.microsoft.com/en-us/power-platform/admin/system-application-users) in Dynamics 365 linked to your Azure AD app registration. This application user will be used by Fours to access Dynamics 365 data via the Web API. ### Create Application User in Dynamics 365 1. In Dynamics 365, go to **Settings** > **Security** > **Users** 2. Change the view to **Application Users** 3. Click **New** and fill in the details: - **User Name**: Enter a name (e.g., `Fours Integration`) - **Application ID**: Enter `1a00a839-496c-488d-a97a-4cdb171b747f` - **Display Name**: Enter a display name (e.g., `Fours Integration`) - **Email**: Enter an email address (can be any valid email) 4. Click **Save** 5. After saving, assign the appropriate security roles to the application user ### Grant Security Roles via Power Platform Admin Center 1. Visit [Power Platform Admin Center](https://admin.powerplatform.microsoft.com/environments) 2. Select the environment you are connecting — its URL looks like `https://{your-org}.crm.dynamics.com` 3. Navigate to **Settings** → **Users + permissions** → **Application users** 4. Click **+ New app user** 5. Add an app: select the Application (client) ID created during Azure integration setup 6. **Business unit**: select the default one (named after your environment, `{your-org}.crm.dynamics.com`) 7. **Security roles**: grant **System Administrator** :::warning If this step is not completed, Fours will not be able to read CRM data. ::: ### Authenticate 1. Navigate to **Settings** > **Integrations** 2. Click **Connect Dynamics 365** 3. Enter your **Tenant ID** and **Instance URL** 4. Click **Verify** to test the connection 5. Once verified, click **Connect** --- ## Create User Integration User-level integration uses OAuth2.0 authorization code flow. Each user authenticates via Microsoft OAuth to access their own Dynamics 365 data. ### Prerequisites - Azure AD **Tenant ID** (provided before OAuth authorization) - Dynamics 365 **Instance URL** (provided before OAuth authorization) ### Before OAuth Authorization Before initiating the OAuth flow, you must provide your Azure AD tenant ID and your Dynamics 365 instance URL on the pre-start form. Both are required to construct the correct OAuth authority, scopes, and API endpoints for your environment. ### Authenticate 1. Click `Connect Now` button in the User Integrations section 2. Enter your **Tenant ID** and **Dynamics 365 Instance URL** when prompted 3. You will be redirected to Microsoft for authentication 4. Sign in with your Microsoft credentials 5. Click **Accept** to grant Fours permission to access your Dynamics 365 data 6. After authorization, you will be redirected back to Fours 7. Verify the integration by clicking the **Verify** button --- ## Edit Integration For security purposes, editing an existing Microsoft Dynamics 365 integration is not allowed. The practical way is to delete it and then recreate it from the beginning. That is also the fix if the org-level card reports that its stored credential can no longer be used — for example after the app registration's secret is rotated or the application user is removed in Dynamics 365. See [Connection health](/integrations/#connection-health). --- ## Delete Integration The Microsoft Dynamics 365 integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the credentials and access tokens will be deleted immediately and permanently from Fours. :::warning - **Org-Level**: To completely delete the integration, please also delete the application user from Dynamics 365 and consider revoking the application permissions from Azure Active Directory. - **User-Level**: Deleting the integration in Fours does not automatically revoke permissions granted in Microsoft. To fully disable access, the user must also revoke the application's permissions. **Steps to revoke Microsoft Dynamics 365 permissions (User-Level):** 1. Go to Microsoft Account → Privacy 2. Select Apps and services 3. Locate the Fours application that was granted Dynamics 365 access 4. Click Remove these permissions ::: --- ## Supported Operations | Operation | Org-Level | User-Level | |-----------|-----------|------------| | Read Data | ✓ | ✓ | | Write Data | ✓ | ✓ | | Sync Data | ✓ (opportunities) | - | | Webhooks | - | - | ### Reading and writing records Both the org-level and the user-level connection can **read and write** Dynamics 365 records, across any entity set the connection's permissions allow — accounts, contacts, opportunities, tasks, and your own custom entities alike. | Capability | What the connection can do | |------------|----------------------------| | **Query records** | Run an OData query against an entity set and page through the matching records | | **Get a record** | Read a single record by its entity set and primary-key GUID | | **Create a record** | Create a new record from the column values you supply, including lookups to related records. Returns the new record's GUID and the record as Dataverse stored it | | **Update a record** | Update columns on an existing record, and read back the stored result | | **Confirm the connection** | Report which Dynamics 365 user the connection is acting as — the quickest way to check that the application user's roles are what you expect | :::caution **Creating a record is not automatically retried.** A create is not a repeatable operation — retrying one that already landed would leave you with a duplicate — so if a create returns an error it is left for you or the agent to resolve deliberately, rather than being attempted again on your behalf. Updates are safe to repeat, because writing the same values twice produces the same record. ::: :::note A write can only do what the connection is allowed to do. On an org connection that is the application user's security roles; on a user connection it is that person's own Dynamics 365 permissions. Granting Fours write access to something is a Dynamics-side decision, made by the roles you assign — not a setting in Fours. ::: ### Dynamics 365 as an Insulin rule destination Because the connection can now write, a Dynamics 365 CRM event can drive a **CRM action** in an Insulin Inbox rule, exactly as Salesforce and HubSpot already could. A rule that fires on a Dynamics 365 opportunity stage change can carry a written instruction — for example *"update the CRM with a short summary of the latest email thread"* — and that instruction lands in the **Needs approval** queue behind a **Run in chat** button. Nothing is written to Dynamics 365 until you click it. See [Insulin → Inbox](/insulin/inbox/) for how rules, destinations, and the approval queue work, including the note on how Dynamics 365 reports won and lost opportunities. ### Opportunity Sync Fours syncs **opportunities** from your Dynamics 365 environment. This runs on the **org-level** connection — it uses the application user's credentials, so it is not tied to any one person staying connected, and its visibility is exactly what you granted that application user's security roles. Opportunity sync is what lets Fours: - Read the opportunities in your environment so they can be turned into co-sell referrals. - Open a specific opportunity from Fours when someone starts a co-sell from a Dynamics 365 record. - Select opportunities automatically against conditions you configure, rather than one at a time. :::info If opportunities are not appearing, it is almost always the application user's permissions. Confirm you completed [Grant Security Roles via Power Platform Admin Center](#grant-security-roles-via-power-platform-admin-center) — without it Fours cannot read CRM data at all. ::: > **Note**: Webhooks are not supported at this time. Dynamics 365 data reaches Fours through the opportunity sync described above rather than by Dynamics 365 pushing change notifications to Fours. --- Source: https://doc.fours.com/integrations/microsoft-outlook/ # Microsoft Outlook Allow Fours to access your Microsoft Outlook account to send, receive, and manage emails on your behalf. --- ## Overview By integrating Fours with Microsoft Outlook, users can leverage automation workflows to enhance email productivity. Tasks such as sending emails can be automated, improving efficiency and enabling customized email workflows tailored to specific business needs. ### Org-Level vs User-Level > **Org-Level**: Not available. Outlook is connected per user only. > > **User-Level**: Each user authenticates via Microsoft OAuth for personal Outlook access. :::note Your connected Outlook account is not used to send the Fours co-sell and commission emails your actions trigger, because Outlook cannot keep those emails in the deal's single email thread. To send them from your own mailbox, connect Gmail as a user integration — see [Send Co-Sell Emails from Your Gmail](/integrations/google-mail/#send-co-sell-emails-from-your-gmail). ::: ## Create Integration (Org-Level) Outlook has no org-level connection. Each person connects their own mailbox — see [Create User Integration](#create-user-integration). ## Create User Integration 1. Click the `Connect Now` button in the User Integrations section, you will be redirected to the Microsoft OAuth2.0 authentication page. > ![Microsoft Outlook Connect Now](images/user_microsoft_outlook_connect_now.jpg) 2. Click the `Accept` button to grant Fours permission to access your Outlook account. This authorization enables Fours to read, send emails on your behalf. > ![Microsoft Outlook User Consent](images/user_microsoft_outlook_user_consent.jpg) 3. After the authorization is granted, you will be redirected to the Fours console. You can see the integration is connected successfully. 4. Verify the integration by clicking the `Verify` button. If the integration is successful, you will see the `Verified` status. ## Fours AI Tools Fours AI works an Outlook mailbox through the actions on a **user-level** Outlook connection, which reach your mailbox through Microsoft Graph. In the agent they carry a `microsoft_email__` prefix. **Mail** | Tool | Description | |------|-------------| | `list-messages` | List messages from a mail folder | | `get-message` | Get one message | | `send-mail` | Send a new email immediately, optionally with file attachments | | `reply-to-message` | Reply to a message's sender, optionally with file attachments | | `reply-all-to-message` | Reply to all recipients of a message | | `update-message` | Update a draft, or the fields of a message that can change | | `move-message` | Move a message to another mail folder | | `copy-message` | Copy a message to another mail folder | | `delete-message` | Delete a message from the mailbox | **Drafts** | Tool | Description | |------|-------------| | `create-draft-message` | Save a new draft, optionally with file attachments | | `send-draft-message` | Send a saved draft | **Attachments** | Tool | Description | |------|-------------| | `list-message-attachments` | List the attachments on a message | | `download-message-attachment` | Download the contents of a file attached to a message | | `add-message-attachment` | Attach one file to a saved draft | **Folders and account** | Tool | Description | |------|-------------| | `list-mail-folders` | List the top-level mail folders | | `list-mail-folder-children` | List the folders inside a mail folder | | `create-mail-folder` | Create a folder inside a mail folder | | `get-account` | Get the connected mailbox's address and display name | `send-mail`, `create-draft-message` and `reply-to-message` attach files in the same call: each file is a name, a MIME type and the file's contents in base64. Microsoft Graph accepts a file attached this way only when it is under 3 MB, and `add-message-attachment` has the same limit ([Attach large files to Outlook messages](https://learn.microsoft.com/en-us/graph/outlook-large-attachments)). If Graph rejects a send, a draft or a reply — an attachment over that limit, for example — the tool fails with Graph's reason; it never reports a message as sent when Graph refused it. ## Edit Integration For security purposes, editing an existing Microsoft Outlook integration is not allowed. The practical way is to delete it and then re-create it from the beginning. ## Delete Integration The Microsoft Outlook integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the credentials and access tokens will be deleted immediately & permanently from Fours. No time window or methods to recover. :::warning - Deleting the integration in Fours does not automatically revoke permissions granted in Microsoft. To fully disable access, the user must also revoke the application's permissions. **Steps to revoke Microsoft Outlook permissions (User-Level):** 1. Go to Microsoft Account → Privacy 2. Select Apps and services 3. Locate the Fours application that was granted Outlook access 4. Click Remove these permissions ::: --- Source: https://doc.fours.com/integrations/microsoft-teams/ # Microsoft Teams Receive instant Fours notifications and alerts in your Microsoft teams channels. --- :::info Fours was formerly named Suger. Inside Microsoft Teams, the app and the channel tab it adds still use the name Suger until the app is renamed. ::: ## Overview By connecting with the Suger app in your Microsoft Teams, you and your team can receive instant notifications and alerts about important sales & revenue events occurring across all your cloud marketplaces. ### Org-Level vs User-Level - **Org-Level**: Uses the Teams app + webhook for organization-wide notifications. Administrators set up the integration for the entire organization. - **User-Level**: Each user connects their personal Microsoft Teams to receive notifications individually. ## Create Integration In your [Fours Console Integration](https://console.suger.io/settings?tab=integrations), you will see the Microsoft Teams integration connection status. Click the `Connect` button to download the `Suger Microsoft Teams app package` and copy the `Binding Token` for future use. > Create Microsoft Teams Integration dialog with the Binding Token to copy and the Suger Microsoft Teams app package download button ### Install Fours Microsoft Teams app 1. Choose the channel you want to send notifications to, then click the `Add a tab` button as shown below. > Add a tab button in Microsoft Teams channel 2. Click **Manage your apps**. > Manage your apps menu option in Microsoft Teams 3. Click button **Upload an app**, then choose the `Suger Microsoft Teams app package` you downloaded. > Upload an app dialog in Microsoft Teams 4. Click button **Add**. > Add button for Suger Teams app package 5. Click button **Set up**. > Set up button for Suger Teams app 6. After the app setup is completed, a new tab named **Suger** will appear in the channel. Click **Suger** tab. > Suger tab added to Microsoft Teams channel 7. In the **Suger** tab, you can change channel name as you like, and paste the **Binding Token** you get from Fours console. click `Save`. Now your channel is bound to Fours console. > Suger tab with binding token field and Save button ### Verify Microsoft Teams Integration After you successfully bind the channel to the Fours console, you will see an integration created on the Fours console. > Microsoft Teams integration listed in Fours Console You need to click the **Verify** button to ensure the bound channel is working. After you click the Verify button, a verification message will be sent to the bound channel. ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the Microsoft Graph Teams API directly. > **Org-level and user-level**: Both integration levels are supported. User-level takes precedence when both are connected. | Tool | Description | |------|-------------| | `msteams_list_teams` | List Teams teams (IDs and display names) | | `msteams_list_channels` | List all channels in a team | | `msteams_list_messages` | List recent messages in a channel | | `msteams_get_message` | Get the full content of a channel message | | `msteams_send_message` | Post a new message to a channel (plain text or HTML) | | `msteams_reply_to_message` | Reply to an existing channel message thread | ## Edit Integration If you have successfully bound multiple channels within Fours, you can specify the channel to which the notification will be sent by default via setting the default channel. > Default notification channel setting for Microsoft Teams ## Delete Integration The Microsoft Teams integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the access token will be deleted immediately & permanently from Fours. No time window or methods to recover. :::warning - To completely delete the integration, please uninstall the **Suger** app from your Microsoft Teams. ::: ## Create User Integration Use user-level integration to receive notifications in your personal Microsoft Teams. 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to Microsoft to authorize 3. Select the channel where you want to receive notifications 4. Return to Fours to confirm connection :::warning Deleting the integration will stop all notifications to your Teams channel. ::: ## Type of Notifications Each type of Notifications consists of the **Entity** and **Action**. There are 2 entity types and 7 action types. They are listed below: | | | | ---------------- | :-------- | | `Entity` | The type of the `entity` who can do `action` is one of:
  • `OFFER`
  • `ENTITLEMENT`
| | `Action` | The action performed. Can be one of:
  • `CREATE`: the entity is created.
  • `PENDING_START`: the entity `ENTITLEMENT` is pending to start.
  • `CANCEL`: the entity is cancelled.
  • `PENDING_CANCEL`: the entity `ENTITLEMENT` is pending to be cancelled.
  • `SUSPEND`: the entity is suspended, it may be reinstated or cancelled in the future.
  • `REINSTATE`: the entity is reinstated from suspended state.
  • `UPDATE`: the entity is updated.
  • `EXPIRE`: the entity `OFFER` is expired
  • `TEST`: for testing purpose only.
| Here is an example of notification you will receive in your Microsoft Teams channel when a new entitlement is created: > Example entitlement notification in Microsoft Teams channel --- Source: https://doc.fours.com/integrations/monday/ # Monday ## Overview Monday integration allows you to connect your personal Monday account to Fours so your workflows can access boards, workspaces, and user-level Monday data. ### Org-Level vs User-Level > **User-Level Only**: Monday integration is configured per user. Each user authenticates with their own Monday account through OAuth. ## Create User Integration ### Authenticate 1. Navigate to Settings > Integrations > User Integrations 2. Click `Connect Monday.com Account` in the Monday section 3. You will be redirected to Monday to authorize access 4. Grant access to your Monday account 5. Return to Fours to confirm the connection :::note Each user connects their own Monday account. Fours stores the OAuth credential securely and does not support manual credential entry for this integration. ::: ## Fours AI Tools When Monday.com is connected, the Fours AI agent can manage boards and work items through Fours' built-in tools (38 actions). Capabilities are grouped below. > **User-level**: Tools run against the connected user's Monday.com account. | Capability | What the agent can do | |------------|-----------------------| | **Boards** | Create, update, and duplicate boards (e.g. `create-board`, `duplicate-board`, `list-boards`) | | **Items** | Manage items and subitems, the core work unit (e.g. `create-item`, `update-item`, `create-subitem`) | | **Item lifecycle** | Move, archive, and delete items across groups and boards (e.g. `move-item-to-group`, `archive-item`) | | **Columns** | Define board schema and set cell values (e.g. `create-column`, `change-column-value`) | | **Groups** | Manage row groups within a board (e.g. `create-group`, `list-groups`) | | **Updates, workspaces & users** | Post activity updates and read org structure (e.g. `create-update`, `list-workspaces`, `get-user`) | ## Edit Integration Editing is not supported. Delete and reconnect if you need to switch to a different Monday account. ## Delete Integration Deleting removes the stored Monday credential from Fours and immediately revokes Fours access to that connected account. :::warning Deleting the integration removes Fours access to Monday immediately. Reconnect the integration if you need to restore access later. ::: --- Source: https://doc.fours.com/integrations/netsuite/ # NetSuite ## Overview [Oracle NetSuite](https://www.netsuite.com) is a cloud-based ERP solution that helps businesses manage finance, CRM, e-commerce, and supply chain operations, providing real-time insights and streamlined processes. ### Org-Level vs User-Level > **Org-Level**: Uses Token-based authentication for organization-wide access. Best for company-wide ERP and billing management. > > **User-Level**: Not typically supported for billing integrations. ## Create Integration (Org-Level) ### Prerequisites Before you start, make sure you have: - **Administrator access** in NetSuite, required to enable features and manage tokens. - Your **NetSuite Account ID**, found in your browser URL (for example, `1234567_SB1` for a sandbox or `1234567` for production). ### Step 1: Enable SuiteCloud Communication Fours communicates with NetSuite using modern protocols that you must turn on manually. 1. Navigate to **Setup > Company > Enable Features**. 2. Click the **SuiteCloud** tab. 3. **Enable Web Services**: Scroll to the **SuiteTalk (Web Services)** section and check both **SOAP Web Services** and **REST Web Services**. 4. **Enable Authentication**: In the **Manage Authentication** section, ensure **Token-Based Authentication** is checked. 5. Click **Save**. ### Step 2: Create the Fours Integration Record This step generates the "Client" credentials that identify Fours to your specific NetSuite instance. 1. Go to **Setup > Integration > Manage Integrations > New**. 2. **Name the integration**: `Fours Connector`. 3. **Authentication**: Select **Token-Based Authentication**. 4. **Security Settings**: Ensure **TBA: IssueToken Endpoint** and **TBA: Authorization Flow** are both **Disabled**. 5. Click **Save**. NetSuite then displays your **Consumer Key (Client ID)** and **Consumer Secret (Client Secret)**. :::warning These keys are displayed **only once**. Copy them immediately into a secure password manager. If lost, you must create a new integration record and start over. ::: ### Step 3: Generate Access Tokens While the integration record identifies *Fours*, the access token is the specific "key" that lets Fours perform actions on behalf of your user. 1. From your NetSuite Home page, go to the **Settings** portlet and click **Manage Access Tokens**. 2. Click **New Token**. 3. **Select Application**: Choose the `Fours Connector` you created in Step 2. 4. **Select User/Role**: Choose the appropriate user and role for this connection. 5. Click **Save**. NetSuite displays the **Token ID** and **Token Secret**. Copy these immediately. ### Step 4: Finalize in the Fours Console Bring all the keys together to open the data pipe. 1. Open the **Fours Console** and navigate to **Settings > Integrations**. 2. Locate the **Oracle NetSuite** card and click **Connect**. 3. **Input credentials**: Paste your **Account ID**, **Client ID**, **Client Secret**, **Token ID**, and **Token Secret**. 4. Click **Create**. A status of **Verified** confirms that Fours is successfully communicating with your NetSuite ledger. ## Edit Integration Editing is not supported. If you rotate your tokens or secrets for security compliance, delete the existing integration in the Fours Console and reconnect using the fresh keys. ## Delete Integration To immediately terminate the connection, click the **Trash** icon next to the integration in the Fours Console. :::warning This does not affect your data in NetSuite. To be thorough, also revoke the access token or the integration record directly within NetSuite. ::: --- Source: https://doc.fours.com/integrations/notion/ # Notion ## Overview Notion is a workspace for notes, docs, wikis, and databases. Connect Notion to Fours so the Fours AI agent can read and manage your Notion pages, databases, and blocks. ### Org-Level vs User-Level > **Org-Level**: Organization-wide access via a Notion internal integration token (shown as "Notion (API Key)"). Shared across your organization. > > **User-Level**: Personal Notion access per user via OAuth. Each user connects their own workspace. ## Create Integration (Org-Level) ### Prerequisites - A Notion **internal integration** and its **Internal Integration Token** (create at [notion.so/my-integrations](https://www.notion.so/my-integrations)) - The Notion pages or databases you want Fours to access must be **shared** with that integration ### Authenticate by API Key 1. Navigate to Settings > Integrations 2. Click **Connect Notion** 3. Enter your Notion **Internal Integration Token** 4. Save, then click **Verify** to confirm the connection ## Create User Integration 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to Notion to authorize 3. Grant access to your Notion workspace 4. Return to Fours to confirm connection ## Fours AI Tools When Notion is connected, the Fours AI agent can read and manage your Notion workspace through Fours' built-in tools (45 actions). Capabilities are grouped below. > **Org-level and user-level**: Both are supported; user-level takes precedence when both are connected. | Capability | What the agent can do | |------------|-----------------------| | **Pages** | Create, read, update, duplicate, move, and archive pages, including markdown export (e.g. `create-page`, `get-page-as-markdown`, `archive-page`) | | **Databases** | Create, retrieve, and update databases and their schema (e.g. `create-database`, `update-database`, `search-databases`) | | **Database queries** | Run filtered, sorted, and paginated queries (e.g. `query-database`, `query-database-filtered`, `query-database-sorted`) | | **Blocks** | Manage page blocks and append typed content — headings, to-dos, callouts, code (e.g. `append-block-children`, `update-block`, `append-todo-block`) | | **Comments** | Create and read comment threads on pages and blocks (e.g. `create-comment`, `list-comments`) | | **Search & users** | Search across the workspace and look up users (e.g. `search`, `list-users`, `get-account`) | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration. :::warning Deleting the integration will remove access to Notion immediately. ::: --- Source: https://doc.fours.com/integrations/oauth2-integration/ # OAuth 2.0 Connect any external service that speaks the OAuth 2.0 standard — such as Salesforce, HubSpot, or a compliant provider of your own — to Fours with the Generic OAuth 2.0 Integration. --- ## Overview The Generic OAuth 2.0 Integration lets you connect Fours to **any** external service that uses the OAuth 2.0 security standard, without needing custom development for each provider. You supply the API credentials from your service provider, and Fours handles the connection, token storage, and renewal. | Term | Meaning for you | | :--- | :--- | | **OAuth 2.0** | A security protocol that lets Fours access data in your service (the provider) without storing your user credentials. | | **Generic Integration** | The ability to connect Fours to any compliant service provider, without provider-specific code. | ### Why use Generic OAuth 2.0? * **Secure vaulting:** Your client secrets and access tokens are encrypted and isolated in an AWS Secrets Manager vault, not left sitting in a database. * **Self-healing connectivity:** Fours monitors each token's time-to-live. When a token is within 5 minutes of expiring, it refreshes silently in the background — no manual intervention. * **Versatile flow support:** From server-to-server data syncing to user-authorized workflows, Fours supports every standard grant type. ## Choose Your Grant Type Before you start, determine which OAuth 2.0 flow your service provider uses. The configuration form adapts to the grant type you select. | Grant Type | Best for | Key requirements | | :--- | :--- | :--- | | **Client Credentials** | Server-to-server sync, where no user login is required. | Client ID, Client Secret, Token URL. | | **Authorization Code** | When a specific user must manually "Allow" access. | Redirect URI, Authorization URL, Client ID/Secret. | | **Refresh Token** | Maintaining long-term access via an existing token. | Existing Refresh Token, Client ID/Secret. | ### Client Credentials * **Usage:** Ideal for server-to-server integrations with no direct interaction from the provider's end user. * **Additional required fields:** None beyond the basic fields. ### Authorization Code * **Usage:** Required when the integration needs explicit authorization from an end user to access data (for example, Sign in with Google or Azure AD). * **Additional required fields:** * **Authorization URL:** Where the user is redirected to grant permission. * **Redirect URI:** The Fours address where the provider sends the code back after authorization. * **Scope:** The specific permissions Fours should have (for example, `read`, `write`, `api_access`). :::warning For the Authorization Code flow, the **Redirect URI** must be registered and allowed in your service provider's API configuration. If you skip this, the handshake fails every time. ::: ### Refresh Token * **Usage:** Lets Fours request a new access token using a long-lived refresh token, minimizing re-authorization. * **Additional required fields:** **Refresh Token** (obtained from a previous authorization). ## Create Integration You configure the integration in the Fours Console. Obtain the API values from the developer panel or API documentation of your service provider. ### Start Setup 1. In the Fours Console, go to **Settings > Integrations**. 2. Click **Connect Now** on the **OAuth 2.0 Integration** card. > ![OAuth 2.0 Connect Now card](images/oauth2_connect_now.jpg) ### Enter Provider Details Fill in the configuration fields. The form shows only the fields relevant to your selected grant type. | Field | Description | | :--- | :--- | | **Label** | A friendly name to identify this integration (for example, "Salesforce Production Integration"). | | **Grant Type** | The OAuth 2.0 flow you want to use (Client Credentials, Authorization Code, or Refresh Token). | | **API Base URL** | The root address for accessing the provider's resources after obtaining the token. | | **Token URL** | The endpoint where Fours requests its tokens. | | **Client ID** | The public identifier provided by your service provider. | | **Client Secret** | The secret key provided by your provider. Keep this confidential. | | **Scope** | (Optional) The specific permissions Fours should have (for example, `read`, `write`, `offline_access`). | | **Tenant ID** | (Optional) Unique identifier that represents a customer. | > ![OAuth 2.0 provider details form](images/connect_to_oauth.jpg) ### Whitelist the Callback URL If you use the **Authorization Code** flow, whitelist Fours' Redirect URI in your service provider's settings before saving: * **Redirect URI:** `https://api.suger.cloud/public/integration/generic_oauth/callback` ## Security and Maintenance This section describes what happens behind the scenes to keep your connection secure and functional. ### Initial Acquisition and Validation When you click **Save**, Fours performs three actions: 1. **Validation:** It immediately fetches a test access token from your provider using the credentials you supplied. If the credentials are wrong, you'll know instantly. 2. **Secure storage:** On successful validation, the **Client Secret** and initial tokens (`access_token`, `refresh_token`) are stored in the AWS Secrets Manager vault, not the main database. 3. **Registration:** The non-confidential configuration (Token URL, Client ID, and a pointer to the secure vault) is recorded in the database. ### Automatic Token Maintenance After the integration is saved, Fours keeps the connection active on every request: 1. **Expiration check:** Before using the access token, Fours checks whether it is close to expiring (with a 5-minute safety buffer). 2. **Renewal:** If the token is near or past expiration and a refresh token is available, Fours requests a new token pair from your provider. 3. **Secure update:** The new access and refresh tokens replace the old ones in the secure vault. 4. **Usage:** The valid access token is provided to whatever service needs to communicate with your provider. This automation ensures you never have to worry about expired tokens. ## Delete Integration Click the **Trash** icon to remove the integration. Deleting permanently wipes all secrets, access tokens, and refresh tokens from both the Fours database and the secure AWS vault. :::warning Deleting the integration in Fours does not revoke the app's permission on the **provider's** side. To be fully secure, also revoke the credentials in your provider's developer portal after deleting the integration in Fours. ::: --- Source: https://doc.fours.com/integrations/okta-sso/ # Okta SSO Manage users with Okta OIDC SSO + SCIM provisioning. --- :::info Fours was formerly named Suger. In Okta, the app — its Okta Integration Network listing, app label, app user profile and **Suger Organization ID** setting — still uses the name Suger until the app is renamed. ::: ## Overview Fours is available on the Okta Integration Network (OIN), offering robust support for both **OIDC Single Sign-On (SSO)** and user provisioning via **SCIM (System for Cross-domain Identity Management)**. By integrating Fours with Okta, you can centralize user authentication and streamline user management across your organization. This guide will walk you through configuring **OIDC SSO** for effortless, secure logins and setting up **SCIM provisioning** to automate user lifecycle management—all directly from your Okta environment. **Supported Features:** - **OIDC SSO:** - Service Provider (SP)-Initiated SSO (logging in from Fours) - Identity Provider (IdP)-Initiated SSO (logging in from Okta) - **SCIM Provisioning:** - **Create Users:** Automatically provision Okta users in Fours. - **Update User Attributes:** Sync user profile changes (e.g., role). - **Deactivate Users:** Automatically deactivate Fours users when they are unassigned in Okta. :::note Users will retain access to Fours via other login methods (e.g., Google SSO or username/password) even after Okta SSO is configured — Fours does not currently block these as long as they exist for the user. This is useful as a fallback if SSO has an issue, but it has one important consequence: **`sugerRole` updates pushed via SCIM only take effect the next time the user signs in through the Okta connection.** If a user keeps signing in via Google or username/password instead, their role changes from Okta will never be applied, with no error shown. To require Okta for every sign-in to your organization, contact [Fours Support](mailto:support@suger.io); Fours turns this on for you, and it is not a self-service setting. Once it is on, password, Google and Microsoft sign-in stop working for your organization's users, and any sign-in (including **Continue with Google**) takes them to Okta. ::: --- ## Configuration Steps The configuration is a four-step process. SSO and SCIM can be set up entirely through self-service in the Fours Console. :::info **Prerequisites:** You must have administrative access to your organization's Okta account. ::: ### Step 1: Initial Okta Setup & Information Gathering First, add the Suger application from the Okta Integration Network (OIN) and enter temporary placeholder values. 1. **Add the Suger App**: - In your **Okta Admin Console**, navigate to **Applications** → **Browse App Catalog**, search for "Suger" (Fours' former name) and add it. - Alternatively, visit the [Suger OIN App page](https://www.okta.com/integrations/suger/) directly. > Suger application listing in the Okta Integration Network catalog 2. **Enter Placeholder Values**: On the "General Settings" screen, enter the following temporary values. These will be replaced with real values provided by Fours Support later. - **Suger Organization ID**: `SugerOrg` (This is a fake organization ID. It will be updated to the your real Fours organization ID later) - **SCIM endpoint URL**: `https://www.fours.com/` - Click **Done**. > Suger app General Settings screen in Okta with placeholder values 3. **Collect OIDC Credentials**: - Open the Suger app in Okta and navigate to the **Sign On** tab. - Copy the **Client ID** and **Client Secret**. - Note your **Okta Domain** (e.g., `dev-12345678.okta.com`). > Sign On tab showing the OIDC Client ID and Client Secret in Okta ### Step 2: Configure SSO Connection Configure your Okta SSO connection through our self-service setup: 1. Navigate to **Settings > SSO** in Fours Console 2. Click **"Set up SSO"** > SSO settings page in the Fours Console 3. The system will generate a secure 24-hour setup ticket and redirect you to the Auth0 configuration wizard > Auth0 SSO configuration wizard with the setup ticket :::note **You can ignore the "Callback URL" field shown in the wizard.** Because you are using the Suger app from the Okta Integration Network (OIN), the callback URL is already pre-configured by Fours — no manual setup is required. ::: 4. Follow the wizard prompts to connect your Okta Identity Provider using the credentials you collected in Step 1 5. The connection will be active immediately upon completion :::warning If you already synced your partner portal's sign-in form (**Partner > Settings > Login Page > Sync to Auth0**), setting up SSO turns off Google, Microsoft, and email-and-password sign-in on that branded form the next time **Settings > SSO** loads, so that form then offers your partners only your organization's own SSO sign-in. If SSO is already set up when you sync, the sync never turns those sign-in methods on. See [Brand the sign-in form](/prm/partner-portal-login-page/#brand-the-sign-in-form-optional). ::: :::tip If you only need SSO authentication, you can stop here. Your Okta SSO is ready to use. User management will be handled manually in the Fours Console. ::: **If you need SCIM user provisioning** for automated user lifecycle management (create, update, deactivate users), continue to Step 3 to configure SCIM directly from the Fours Console. :::info SCIM provisioning provides automated user creation, updates, deactivation, and role mapping. This is optional and only needed if you want full user lifecycle automation. ::: ### Step 3: Configure SCIM Provisioning (Optional) :::note This step is only required if you need SCIM user provisioning. If you only configured SSO in Step 2, you can skip this section. ::: You can generate the SCIM credentials directly from the Fours Console: 1. **Navigate to the SCIM Configuration**: In the Fours Console, go to **Settings > SSO**. Find your SSO connection and click the **SCIM** dropdown to expand the SCIM provisioning section. > Expanded SCIM provisioning section in the Fours Console SSO settings 2. **Generate a SCIM API Token**: Click **"+ Generate New Token"**. A dialog will appear with your token. > Generate New Token dialog showing the SCIM API token :::warning **Copy and save your SCIM API Token immediately.** Fours does not store this token — you will not be able to view it again. If you lose it, you can delete the token and generate a new one. ::: 3. **Copy the SCIM Credentials**: After the token is generated, the following information will be available in the SCIM section. Copy them for use in Okta: - **Organization ID** - **SCIM Endpoint URL** - **SCIM API Token** (from the previous step) > SCIM section showing Organization ID and SCIM Endpoint URL Use these values to complete the setup in Okta. #### A. Update General Settings 1. In the Suger app in Okta, navigate to the **General** tab and click **Edit** in the "App Settings" section. 2. Replace the placeholder values with the **Suger Organization ID** and **SCIM Endpoint URL** provided by Fours Support. > Editing App Settings with the Suger Organization ID and SCIM Endpoint URL :::warning - Ensure the **SCIM endpoint URL** ends with a trailing slash (`/`). - Ensure the **Suger Organization ID** has no leading or trailing spaces. ::: #### B. Configure SCIM Provisioning 1. **Enable API Integration**: - Navigate to the **Provisioning** tab and click **Configure API Integration**. - Check **Enable API Integration**. - Paste the **SCIM API Token** provided by Fours Support into the "API Token" field. - Click **Test API Credentials**. A success message should appear. - Click **Save**. > API Integration settings with the SCIM API token in Okta Provisioning 2. **Enable Provisioning Features**: - In the "Provisioning to App" section, click **Edit**. - Enable **Create Users**, **Update User Attributes**, and **Deactivate Users**. - Click **Save**. > Provisioning to App settings with user lifecycle options enabled 3. **Map User Roles**: To manage user roles (Admin, Editor, Viewer) in Fours via Okta, you must create a custom attribute and map it. - **Create a Custom Attribute on the Okta User Profile**: - Go to **Directory** → **Profile Editor** → **Okta** → **User (default)** profile and click **Edit**. - Add a new attribute with the following settings: - **Data type**: `string` - **Display name**: `Suger Role` - **Variable name**: `sugerRole` - Check **Define enumerated list of values** and add the following members: - `ADMIN` - `EDITOR` - `VIEWER` - **Default value**: `VIEWER` - Click **Save**. > Custom sugerRole attribute added to the Okta user profile - **Create a Custom Attribute on the Suger App User Profile**: - Go to **Directory** → **Profile Editor** → **Apps** → **Suger App user** profile and click **Edit**. - Add a new attribute with the following settings: - **Data type**: `string` - **Display name**: `Suger Role` - **Variable name**: `sugerRole` - **External name**: `roles.^[type=='SUGER_ROLE'].value` - **External namespace**: `urn:ietf:params:scim:schemas:core:2.0:User` - **Enum**: Define enumerated list of values - **Attribute members**: `ADMIN`, `EDITOR`, `VIEWER` - **Attribute required**: `Yes` - **Attribute type**: `Group` - Click **Save**. > Custom sugerRole attribute added to the Suger App user profile - **Map the Attribute to the Suger App**: - In the Suger app in Okta, navigate to the **Provisioning** tab → **To App** section. - Find the `sugerRole` attribute and set the mapping: - **Attribute value**: `Map from Okta Profile` - Select `sugerRole` from the dropdown. - **Apply on**: `Create and update` - Click **Save**. > sugerRole attribute mapping in the Okta Provisioning To App section ### Step 4: Assign Users in Okta (Required for SCIM Only) :::note This step is only required if you configured SCIM provisioning in Step 3. If you only configured SSO, users can log in directly after the SSO connection is active. User management will be handled in the Fours Console. ::: Instead of assigning roles to individual users, the best practice is to assign users to Okta groups that correspond to Fours roles. 1. **Create Okta Groups**: Create three Okta groups, one for each role, for example `Suger Role Admin`, `Suger Role Editor`, and `Suger Role Viewer` as in the screenshots. The names are up to you: the role comes from the `Suger Role` value you set when you assign each group in the next step. > Creating Suger role groups in Okta 2. **Assign Groups to the Suger App**: - Navigate to the **Assignments** tab of the Suger app. - Assign each of the three groups to the application. - When assigning each group, override the `Suger Role` attribute to the corresponding value (`ADMIN`, `EDITOR`, or `VIEWER`). > Assigning the Suger Role attribute value when adding a group > > Suger role groups assigned to the Suger app in Okta 3. **Manage Users**: - To grant a user access, add them to one of the Fours role groups in Okta. - To revoke access, remove the user from the group. - The Suger app will now appear on the Okta dashboard for assigned users. > Suger app icon on the Okta end-user dashboard --- ## Using the SSO Connection - **Identity Provider (IdP)-Initiated**: Click the Suger app icon from the Okta end-user dashboard. - **Service Provider (SP)-Initiated**: - Navigate to `https://console.suger.io/login?orgId={your_suger_org_id}`. After the first login, a shortcut will appear on the main login page https://console.suger.io/login and you can omit the `orgId` parameter. > Fours login page with the organization SSO shortcut button - Click **"Continue with Okta"** to authenticate with your Okta credentials. (Note: This step is automatically skipped if Okta is configured as the default SSO connection. To stop offering Google or username/password sign-in altogether, see the note at the top of this page.) > Continue with Okta button on the Fours login page ### Note :::warning Once this integration is active, all user management (creation, deactivation, and role changes) **MUST** be done in Okta. Manual changes in the Fours console will be overridden by Okta. ::: --- ## Troubleshooting 1. **"Conflict" or "Matching user not found" error** - If you encounter this error when assigning users to the SCIM app, navigate to **Dashboard > Tasks** to check the error details and retry the task. - If the error persists, verify the SCIM endpoint URL and API token. Ensure the SCIM endpoint URL ends with a `/`. 2. **"The connection is not enabled" error** - Check the "Auth0 Enterprise Connection Name" setting in the Fours console under Settings > Organization. Ensure the Okta connection name is correct and does not contain any extra characters such as spaces. 3. **User provisioning** - SCIM provisioning a user (via Okta) only creates their identity ahead of time — it does **not** immediately create a visible Fours account. - The user will not appear in the Fours console, and will not have a role assigned, until they complete their first login via Okta SSO. Okta reporting "Success" for a push/sync does not mean the user is visible in Fours yet. 4. **SCIM provisioning for `sugerRole` updates** - To apply `sugerRole` updates, log out and then log back into the Fours console. - Updates to `sugerRole` may take a few minutes to reflect due to caching. Please wait a while and try again. 5. **Synced user attributes** - Only `email` and `sugerRole` are synchronized. - Changes to the family name and given name will **NOT** be reflected in the Fours console. 6. **User deprovisioning** - After a user is un-provisioned, they will lose access to the Fours console upon their next login attempt. However, they can continue accessing the Fours console until their current session expires. - The user will still be visible in the Fours console, and removal may take up to **24 hours**. 7. **"400 Bad Request" error during login** - This error typically indicates a mismatch in the OIDC client credentials. Double-check that the **Client ID** and **Client Secret** you generated in Okta (Step 1) were correctly sent to and configured by Fours Support. 8. **"JIT user provisioning is disabled" error during login** - In Okta, navigate to the **Assignments** tab of the Suger app. - Look for a red icon next to the user, which indicates a provisioning failure. - Try to resolve the issue by removing and re-assigning the user to the application. - If the error persists, contact Fours Support for assistance. 9. **MFA prompt appears even though Okta already enforces MFA** - Fours currently enforces its own MFA independent of your identity provider's MFA policy. There is no setting yet to disable Fours' MFA when SSO/Okta MFA is already in place — if this double-prompting is a problem for your users, contact Fours Support to flag it as a feature request. If you have any further questions, please contact Fours support at [support@suger.io](mailto:support@suger.io). --- Source: https://doc.fours.com/integrations/openai/ # OpenAI Connect your OpenAI API key for unlimited features at cost. --- ## Overview By integrating your OpenAI account with Fours, you can utilize your own OpenAI API key. This allows you to access certain AI-powered features within Fours, with billing for API usage handled directly by OpenAI. ### Org-Level vs User-Level Fours supports two levels of OpenAI integration: - **Org-Level**: Uses OpenAI API key for org-wide access. Suitable for GPT model access across your organization. API usage is billed to the organization. - **User-Level**: Uses Codex for personal workspace access. Suitable for individual developers who want to use Codex in their personal workflow. --- ## Create Integration 1. Navigate to the [Fours Console Integration](https://console.suger.io/settings?tab=integrations) page. 2. Find the **OpenAI** integration and click the `Connect` button. 3. In the dialog that appears, provide the following information: - **API Key**: Your OpenAI API key for accessing GPT models. - **Organization ID** (Optional): Your OpenAI organization ID, if you belong to multiple organizations. > OpenAI integration dialog with API key fields ## Edit Integration You can edit the existing integration to update the following field: - **Organization ID** (Optional): Your OpenAI organization ID. > Editing the OpenAI integration Organization ID Editing the API key is not supported. To change the API key, you must delete the current integration and create a new one. ## Delete Integration You can delete the OpenAI integration at any time. Please be aware that this action is irreversible and will permanently remove the integration credentials. --- ## Create User Integration (Codex) Use user-level integration when you want to use Codex for your personal workspace. 1. Click `Connect Now` button in the User Integrations section 2. You will be redirected to OpenAI to authorize 3. Grant access to your Codex workspace 4. Return to Fours to confirm connection :::warning Deleting the integration will remove access to Codex immediately. ::: --- Source: https://doc.fours.com/integrations/openrouter/ # OpenRouter Connect your OpenRouter API key to run Fours' AI features on the models OpenRouter serves. --- ## Overview OpenRouter is an AI model provider (category: AI). By connecting your own OpenRouter API key (bring-your-own-key), the models OpenRouter offers become selectable in Fours' model picker — for Insulin agents, chat, inference, and knowledge-base embeddings. API usage is billed directly by OpenRouter to your account; Fours does not charge for these models. ### Org-Level vs User-Level - **Org-Level**: the key is shared across your organization. Its models are available to organization-level agents and to members of the org. Connecting requires an organization admin. - **User-Level**: the key is personal to your workspace. Its models are available to your own user-level agents and personal Insulin. --- ## Create Integration 1. Navigate to the [Fours Console Integrations](https://console.suger.io/settings?tab=integrations) page. 2. Find the **OpenRouter** integration and click **Connect**. 3. Choose the level — **Organization** (shared) or **User** (personal). 4. Paste your **OpenRouter API Key** and click **Save credentials**. Fours verifies the key with OpenRouter before storing it, so an invalid key is rejected at connect time rather than surfacing later as a failed model run. > Generate an API key in your OpenRouter account at [openrouter.ai](https://openrouter.ai/) (**Keys**). :::info After connecting, open any model picker — an agent's **Default Model**, or **Insulin model settings** — and OpenRouter's models appear, with verified models grouped first and each entry attributed to OpenRouter. ::: ## Edit Integration Editing the API key is not supported. To change the key, delete the integration and create a new one. ## Delete Integration You can delete the OpenRouter integration at any time. This permanently removes the stored credential. Any agent pinned to an OpenRouter model then shows that model as **unavailable** with a reconnect prompt until you reconnect OpenRouter or pick another model — Fours never silently substitutes a different model. :::info OpenRouter also serves knowledge-base embeddings on your own key: **OpenRouter · BGE-M3** appears in the embedding-model chooser once this integration is connected at the knowledge base's level — an organization connection for an organization knowledge base, your personal connection for a private one. Organization knowledge bases can also use the Fours-hosted models, which need no key — see [Knowledge Bases](../../insulin/knowledge-base/). ::: --- Source: https://doc.fours.com/integrations/orb/ # Orb Automate the usage metering from Orb to all cloud marketplaces. --- ## Overview If you're currently dependent on [Orb](https://www.withorb.com/) for your metering and billing services and are aiming to grow your presence in cloud marketplaces, Fours presents the perfect solution to bridge this transition. Through our no-code, fully automated integration, you can effortlessly measure usage within your existing Orb setup and allocate it to clients across various cloud marketplaces. This integration eliminates the necessity for migration or complex engineering work, ensuring a seamless and trouble-free process. :::warning In the `quantity` and `invoice` billing modes, this integration does not disambiguate between a buyer's [AWS Concurrent Agreements](/aws-marketplace/integration/#enable-concurrent-agreements) for the same product — usage can be attributed to the wrong agreement. In `amount` mode Fours does not guess: when more than one of a buyer's entitlements carries the `orb` dimension — directly or through your dimension mapping — it reports nothing for that buyer (see [Billing Mode](#billing-mode)). If your product has Concurrent Agreements enabled, report usage through Fours directly instead. See [Usage Metering for AWS Concurrent Agreements](/metering/usage-metering/#usage-metering-for-aws-concurrent-agreements). ::: ## Create Integration In your [Fours Console Integration](https://console.suger.io/settings?tab=integrations), you will see the **Orb** integration connection. Click the `Connect` button to create an integration with your Orb instance. This will open an dialog for you to input - **API Key**: The Orb API key can be issued in the Orb's console. Here is the [auth guidance](https://docs.withorb.com/essentials/postman#authentication). - **Billing Mode**: `quantity`, `amount`, or `invoice`. If it is quantity, Fours fetch & report the billable metrics by quantity. If it is amount, Fours fetch & report the billable metrics by amount/cost. If it is invoice, Fours reports each issued Orb invoice's total to the cloud marketplace once. See [Billing Mode](#billing-mode) for details. > Orb integration connection dialog with API key and billing mode Once the integration process is finished, you can proceed by clicking the `VERIFY` button. This action triggers the Fours service to test the connection to the APIs of your Orb instance. If everything is configured correctly, the integration status will be updated as `VERIFIED`. ## Edit Integration Editing an existing Orb integration is supported. Click the `Edit` button to open the dialog of editing Orb integration as shown below. - **Enable Auto Report Usage**. You can choose to enable or disable the automatic usage report feature for Orb. Enabling this feature allows Fours to run a cron job **once a day** to retrieve the aggregated subscription usages, costs, or issued invoice totals from Orb and report them as UsageRecordGroups to the [Fours metering API](/metering/usage-metering/). On the other hand, disabling this feature means that no cron job will be scheduled for this purpose. - **Enable Auto Report Credit**. Shown only when Billing Mode is `amount` and Auto Report Usage is enabled. When enabled, Fours nets out the prepaid Orb credits a buyer consumes. For each reporting window, Fours reads the credit Orb applied and subtracts it from the amount metered to the cloud marketplace. - **Billing Mode**: `quantity`, `amount`, or `invoice`. If it is quantity, Fours fetch the billable metrics by quantity. If it is amount, Fours fetch the billable metrics by amount/cost. If it is invoice, Fours reports each issued Orb invoice's total to the cloud marketplace once. - **Plans**. All available price plans in your Orb instance. The `source dimension keys` with the price for each type of price plans can be found here. - **Billable Metrics**. The full list of billable metrics fetched from Orb for all available Orb customers. It is auto fetched from Orb, not editable. ## Delete Integration The Orb integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the API Key will be deleted immediately & permanently from Fours. No time window or methods to recover. ## Billing Mode There are three billing modes available for Fours-Orb integration: **quantity**, **amount**, and **invoice**. - **quantity**: Fours fetches the per-period usage quantities of each billable metric from the Buyer's active Orb subscription and reports them to the mapped cloud marketplace dimensions. - **amount**: Fours fetches the per-period subscription costs from Orb and reports them on the single source dimension key `orb` (unit price $1). They go to whichever of the buyer's entitlements carries `orb`: either the entitlement has a dimension keyed or named `orb`, or — with **Enable Dimension Mapping** turned on for that marketplace in [Metering Dimension Conversion](/metering/usage-metering/#metering-dimension-conversion) — it has the dimension `orb` is mapped to. If none of them does, or more than one does, that buyer's usage is not reported for the run. Other buyers' usage still is, and the run then ends as failed so the skipped buyer is not mistaken for a successful report. - **invoice**: Fours fetches each issued Orb invoice's total and reports them on the single source dimension key `orb`. See [Invoice Mode](#invoice-mode) below. The following table details how to configure the source dimension keys in [metering dimension conversion](/metering/usage-metering/#metering-dimension-conversion) for the `quantity` and `amount` modes. | | Price Example | `quantity` | `amount` | | ---- | --- | ----------- | ---------- | | Unit |
  • `compute`: $0.02/unit
  • `storage`: $0.03/unit
|
  • `compute`: $0.02/unit
  • `storage`: $0.03/unit
|
  • `orb`: $1/unit
| | Tiered |
  • `compute`: $0.02/unit in range[0, 100)
  • `compute`: $0.01/unit in range[100, ∞)
|
  • `compute_tiered_0`: $0.02/unit
  • `compute_tiered_100`: $0.01/unit
|
  • `orb`: $1/unit
| | Bulk |
  • `compute`: $0.03/unit up to 100
  • `compute`: $0.02/unit up to 200
  • `compute`: $0.01/unit up to ∞
|
  • `compute_bulk_100`: $0.03/unit
  • `compute_bulk_200`: $0.02/unit
  • `compute_bulk_0`: $0.01/unit
|
  • `orb`: $1/unit
| | Package |
  • `compute`: $0.2 per 100 unit
|
  • `compute_package_100`: $0.2/unit
|
  • `orb`: $1/unit
| | BPS | |
  • :no_entry_sign: not supported
|
  • `orb`: $1/unit
| | Matrix |
  • `compute` `us-west-1` `gcp`: $0.01/unit
  • `compute` `us-west-1` `aws`: $0.02/unit
  • `compute` `us-west-2` `gcp`: $0.03/unit
  • `compute` `us-west-2` `aws`: $0.04/unit
|
  • `compute__matrix__us-west-1__gcp`: $0.01/unit
  • `compute__matrix__us-west-1__aws`: $0.02/unit
  • `compute__matrix__us-west-2__gcp`: $0.03/unit
  • `compute__matrix__us-west-2__aws`: $0.04/unit
|
  • `orb`: $1/unit
| :::warning - If `quantity` is selected as the Billing Mode, please ensure all source dimension keys in your price plans have been mapped to their respective cloud marketplace dimensions in the [Metering Dimension Conversion](/metering/usage-metering/#metering-dimension-conversion). - If `amount` or `invoice` is selected as the Billing Mode, please ensure the source dimension key `orb` is mapped to the cloud marketplace dimensions. - Orb Auto Fetch & Report Job: In case any billable metrics from Orb cannot be successfully converted to metering dimensions in the cloud marketplace, it may result in the entire Orb auto fetch and report job failing. - If you notice any discrepancies or missing usage reporting, please verify whether this is caused by incomplete mapping of billable metrics to cloud marketplace dimensions. If so, rectify the mapping accordingly to ensure accurate reporting. ::: ### Invoice Mode In `invoice` mode, Fours reports issued Orb invoice totals. During each sync run, Fours fetches the invoices of the connected Orb Customers from the last two calendar months and handles each invoice by its status: - **Issued**: The invoice's total amount is reported to the cloud marketplace exactly once. After reporting, Fours stamps the Orb invoice with metadata `suger_usage_record_group_id`. - **Void**: If a voided invoice was previously reported, Fours automatically credits the reported amount back to the buyer's entitlement. - **Draft / Paid / Synced**: Skipped. ## Connect Orb Customer To enable Fours to fetch and report the billable metrics of Orb Customers to the appropriate entitlements in Cloud Marketplace, you need to connect the Buyer in Fours with the corresponding Customer in Orb. Simply click the `Edit` button in the Buyer and add the corresponding Orb Customer ID. This setup only needs to be done once; afterward, Fours' service will automatically retrieve the latest billable metrics and report them to the correct Cloud Marketplace entitlements. --- Source: https://doc.fours.com/integrations/people-data-labs/ # People Data Labs ## Overview People Data Labs provides comprehensive person and company data APIs, including professional profiles, employment history, and company information. Integrate with People Data Labs to enrich lead and account data with verified professional information. ### Org-Level vs User-Level > **Org-Level**: Uses API key for organization-wide data enrichment. Best for bulk data enrichment operations. > > **User-Level**: Not applicable - People Data Labs is an API-only service. ## Create Integration (Org-Level) ### Prerequisites - People Data Labs account with API access - People Data Labs API key ### Authenticate by API Key 1. Navigate to Settings > Integrations 2. Click "Connect People Data Labs" 3. Enter your People Data Labs API key 4. Verify the connection ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration from Fours. :::warning This does not delete your People Data Labs account or any cached data. Check People Data Labs for any additional API key cleanup if needed. ::: --- Source: https://doc.fours.com/integrations/posthog/ # PostHog ## Overview PostHog is a product-analytics platform for tracking user behavior, running experiments, managing feature flags, and building insights and dashboards from event data. Connect PostHog to Fours so the Fours AI agent can query your product analytics — pulling events, insights, and cohorts, inspecting feature flags and experiments, and surfacing usage trends — so product signals inform your marketplace and revenue workflows. ### Org-Level vs User-Level > **Org-Level Only**: PostHog connects at the organization level using a PostHog Personal API Key. The connection is shared across your organization. ## Create Integration (Org-Level) ### Prerequisites - A PostHog account with a **Personal API Key** (PostHog → **Settings → Personal API Keys**) scoped to the resources you want Fours to access - Your PostHog **region host** — `https://us.posthog.com` (default) or `https://eu.posthog.com` for EU ### Authenticate by API Key 1. Navigate to Settings > Integrations 2. Click **Connect PostHog** 3. Paste your PostHog **Personal API Key** 4. Set your **host** (`https://us.posthog.com` by default, or `https://eu.posthog.com` for EU) 5. Save, then click **Verify** to confirm the connection :::note The PostHog **project ID** is supplied per request by the AI agent, so it is not part of the connection form — you only provide the Personal API Key and host. ::: ## Fours AI Tools When PostHog is connected, the Fours AI agent can query and manage your PostHog project through Fours' built-in tools (66 actions). Capabilities are grouped below. > **Org-level**: Tools run against the organization's connected PostHog project. | Capability | What the agent can do | |------------|-----------------------| | **Events & capture** | Ingest and query events (e.g. `capture-event`, `list-events`, `identify-person`) | | **Persons & identities** | Manage user profiles (e.g. `create-person`, `get-person`, `list-persons`) | | **Insights & dashboards** | Build analytics insights and dashboards (e.g. `create-insight`, `list-insights`, `create-dashboard`) | | **Feature flags & experiments** | Manage flags and A/B experiments (e.g. `create-feature-flag`, `create-experiment`) | | **Cohorts & actions** | Define segmentation cohorts and saved event patterns (e.g. `create-cohort`, `create-action`) | | **Definitions & metadata** | Inspect event and property definitions (e.g. `list-event-definitions`, `get-property-definition`) | | **Alerts, annotations & surveys** | Manage alerts, annotations, and surveys (e.g. `create-alert`, `create-annotation`, `create-survey`) | | **Projects & session recordings** | List projects and session recordings (e.g. `list-projects`, `list-session-recordings`) | ## Edit Integration Editing is not supported. Delete and recreate. ## Delete Integration Deleting removes the integration and revokes the stored PostHog credential from Fours. :::warning This does not delete any data in PostHog. You may also want to revoke the Personal API Key in PostHog (**Settings → Personal API Keys**). ::: --- Source: https://doc.fours.com/integrations/salesforce/ # Salesforce Integrate Fours with Salesforce to create private offers, manage contracts, and co-sell across AWS, Azure & GCP Marketplaces directly from your CRM. :::info Fours was formerly named Suger. Inside Salesforce, the package (Suger Connector) — its AppExchange listing, app, tabs, permission sets, components, quick actions and reports — still uses the name Suger until the package is renamed. ::: ## Overview This guide walks you through integrating Salesforce with Fours, enabling your sales and business teams to: - **Create marketplace offers** directly from Salesforce opportunities - **Manage co-sell referrals** within your existing CRM workflow - **Sync opportunity data** between Salesforce and marketplace platforms - **Streamline collaboration** between sales teams and marketplace operations ### How the integration works | | | | --- | --- | | **Direction** | Two-way. Offers and referrals are created from Salesforce and pushed to the marketplace; marketplace state and enrichment data flow back onto Salesforce records. | | **Source of truth** | Salesforce owns the opportunity and account records. Fours owns offers, entitlements, referrals and marketplace state, and writes them onto the linked Salesforce records. | | **Scope** | Organization-level — the managed package is installed once per Salesforce org. | | **Scheduled jobs** | CRM enrichment every **2 hours**. Backfill of Fours objects into Salesforce every **4 hours**. Auto-share every **3 hours**. Salesforce schema sync **daily**. | | **Limits** | A scheduled enrichment run processes at most **20,000 Salesforce records**, and is cut off after 105 minutes so a wedged run cannot block the next one. | ### When something fails - **A failing object type does not stop the rest.** Record writes are sent with `allOrNone: false` in batches of 200, so a rejected record does not roll back the batch — per-record outcomes are collected and the run moves on to the next object type. - **The 4-hourly backfill does not retry itself.** It is deliberately single-attempt: a re-run part-way through could duplicate records that have no external ID to upsert against. The next scheduled pass picks the work up instead. - **Enrichment activities do retry** — 2 to 3 attempts with exponential backoff starting at 1 second. - **An expired session is recovered silently.** A `401 INVALID_SESSION_ID` makes Fours reload the stored credential and retry once. A `400 invalid_grant` means the refresh token is no longer usable: Fours stops, flags the integration as needing re-authorization, and notifies you rather than retrying into a lockout. - **Fields that do not exist in your org are skipped, not failed.** If a mapped field is missing from your Salesforce schema, that field is dropped from the write and logged; the rest of the record still syncs. :::warning Fours owns every `Suger__*__c` record it writes and re-upserts them on each backfill. **Manual edits to those records are overwritten.** The one exception is a link that bulk link writes to an offer lookup Fours doesn't otherwise manage, which Fours writes only once — see [Sync behavior notes](#sync-behavior-notes). Native `Opportunity` and `Account` records are only written where you have explicitly mapped enrichment fields. ::: ## Prerequisites - A **Salesforce Administrator** account - A **Fours organization** account and **API Key** (see [Authenticate with the Fours API](/settings/oauth-app/)) - Installation link for the **Salesforce package** (Production or Sandbox) - A **current version of the Fours managed package**, if you want the fields described under [Package Fields and Sync Behavior](#package-fields-and-sync-behavior). Those fields ship with the package, so an org on an older version will not receive that data until it upgrades. ## Installation ### Install the Salesforce Package Install the Fours package from the [AppExchange](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3u00000RMskLEAT): 1. Click **Get it Now** > Get It Now button on the Suger AppExchange listing 2. Log in with your Salesforce Admin account 3. Choose Install in **Production** (or **Sandbox**) 4. Select Install for **Admins Only** / **All Users** / **Specific Profiles** 5. Click Install ### Set Up Integration User To connect Fours with Salesforce, you need a dedicated Integration User account. This user will authenticate via [OAuth 2.0 Web Server Flow](https://help.salesforce.com/s/articleView?language=en_US&id=sf.remoteaccess_oauth_web_server_flow.htm&type=5) and allow Fours to communicate with your Salesforce org using REST APIs. Creating a dedicated Integration User ensures: - Secure and isolated access for API calls - Easier troubleshooting and monitoring - No dependency on personal user accounts #### Choose a License Type When creating the Integration User, select one of the following license types: | License Type | When to Use | Notes | | ---------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | | **Salesforce License** | Required if your field mapping involves any Quote object — **standard Quote (`Quote`)** or **CPQ Quote (`SBQQ__Quote__c`)** | You must also assign a **CPQ license** to the user if you are using CPQ. The Salesforce Integration License does not grant access to Quote objects. | | **Salesforce Integration License** | Recommended in most cases | Free license, limited to API-only users (cannot log in via UI). Use with **Salesforce API Only System Integrations profile** | #### Create the Integration User 1. In Salesforce Setup, go to **Users** → **New User**. > New User creation page in Salesforce Setup 2. Enter a valid email address (required for activation). 3. Assign one of the licenses listed above. 4. For **Salesforce Integration License**, assign the **Salesforce API Only System Integrations** profile. 5. Save and activate the user. #### Assign Permission Sets After creating the user, assign the necessary permission sets depending on the license type. For more details, see [Assign Fours permission sets to your team](/salesforce-app/salesforce-app-assign-permission-sets/). If using **Salesforce License**: - Assign the **Suger Integrator** permission set. - Create an additional permission set granting **Read** and **View All** access on: - Account - Contact - Opportunity - Any other objects/fields required in your field mapping If you are using **standard Quote**, grant **Read** access to **Product2**, **Pricebook2**, and **Quote**. The combination of these three permissions also grants access to **QuoteLineItem** (no separate permission is required). If using **Salesforce Integration License**: - Assign the **Suger Integrator (Salesforce Integration License)** permission set. - Create a new permission set (with Salesforce API Integration as the license type) granting **Read** and **View All** access on: - Account - Contact - Opportunity - Any other objects/fields required in your field mapping - When creating this permission set, be sure to select **Salesforce API Integration** as the license. Note that it is **Salesforce API Integration**, NOT **Salesforce Integration**. At this point, your Integration User is ready. You can now proceed to connect Salesforce and Fours via OAuth in the next step. ## Configuration To enable two-way communication, you need to: 1. Allow Salesforce → Fours (enter Organization ID and API Key in Salesforce). 2. Allow Fours → Salesforce (authorize access via OAuth). ### Configure Salesforce to Access Fours This step configures Salesforce so it can call Fours APIs. 1. Get your Organization ID and API Key - **Organization ID**: found in Fours Console → **Settings** → **[Organization & Users](https://console.suger.io/settings?tab=organization)** > Organization ID field under Organization and Users in Fours Console - **API Key**: generate in Fours Console → **Settings** → **[API Client](https://console.suger.io/settings?tab=api_client)** - Follow the instructions at [API Client](/settings/oauth-app/#create-api-client-with-api-key) 2. Open Suger app in Salesforce - In Salesforce, search for Suger under Apps and open it. > Suger app search result in the Salesforce App Launcher 3. Enter settings in Salesforce - Go to Settings inside the Suger app. - Fill in: - **Organization ID** - **API Endpoint**: `https://api.suger.cloud` - **API Key** (check no trailing spaces) - Click Save. > Suger app settings form in Salesforce with Organization ID and API Key ### Configure Fours to Access Salesforce This step configures Fours Console to connect to Salesforce using the Integration User. 1. Go to [Integrations](https://console.suger.io/settings?tab=integrations) in Fours Console - Navigate to Settings → Integrations → Salesforce. - Click Connect Now. > Connect Now button on the Salesforce integration page in Fours Console 2. Select Environment - Enter your **Salesforce Subdomain** (e.g., acme.my.salesforce.com). - Check Sandbox if you are connecting to a sandbox org. > Salesforce connection form with subdomain and sandbox checkbox - Click Create Find your **Salesforce Subdomain** in Salesforce Setup → Company Settings → My Domain. 3. Verify the connection - Click Verify. > Verify button for the Salesforce connection in Fours Console #### Use Your Own External Client App By default, Fours connects using its own managed OAuth app — you only need to enter your subdomain and click **Create**. If you prefer to connect with **your own** Salesforce External Client App (ECA) instead, toggle **Custom External Client App** on the connect form and enter its **Consumer Key** and **Consumer Secret**. First, create the External Client App in Salesforce (**Setup → External Client App Manager → New External Client App**) and configure its OAuth settings: - **Callback URL**: `https://api.suger.cloud/public/integration/salesforce/oauthCallback` - **OAuth scopes**: - **Manage user data via APIs** (`api`) - **Perform requests at any time** (`refresh_token`, `offline_access`) — **required**. Without it Salesforce returns no refresh token and Fours rejects the connection (otherwise it would stop working once the first access token expires). - **Access the identity URL service** (`id`) — optional; only needed if you enable **Change Data Capture (real-time sync)**, which uses your Salesforce org ID. Core sync, offers, and co-sell work without it. - Under **Flow Enablement**, enable **Authorization Code and Credentials Flow** (the flow Fours uses). - Under **Security**, enable **Require Proof Key for Code Exchange (PKCE)**. - Leave **Enforce Refresh Token IP Allowlist** disabled, unless you add Fours' egress IPs to the allowlist (otherwise token refresh will fail). > External Client Apps have no "valid until revoked" setting (that's a classic Connected App option). There is no fixed refresh-token expiry to configure; the only expiry is the optional **Limit Idle Refresh Token TTL to 30 Days**, which never triggers for an active integration that refreshes regularly. Then enter the **Consumer Key** (as Client ID) and **Consumer Secret** on the Fours connect form and click **Create**. :::note The Consumer Secret is stored encrypted and is never exposed back to the browser. If you later rotate the secret in Salesforce, delete and recreate the integration to update it — editing it in place isn't supported. ::: ### Choose What Backfills to Salesforce The scheduled backfill (every 4 hours) copies Fours objects into the Fours custom objects in your Salesforce org. You choose which objects it copies, and how far back it reaches, on the Salesforce integration's **Backfill To Salesforce Configuration** tab. Editing the integration requires the **Admin** role. 1. Go to [Integrations](https://console.suger.io/settings?tab=integrations) in Fours Console, open the **⋯** menu on the Salesforce card, and click **Edit**. 2. Open the **Backfill To Salesforce Configuration** tab. 3. For each object, turn **Sync** on or off. With Sync on, choose **All** to backfill every record, or choose **Days Back** and enter a number of days from 1 to 365 to backfill only recent records. 4. Click **Save**. A new Salesforce integration starts with these settings: | Object | Default | | --- | --- | | Referral, Offer, Entitlement, Product, Contact | Sync on — **All** | | Buyer, OfferDimension, OfferPaymentInstallment | Sync on — **Days Back**, 30 days | | RevenueRecord, FundingRequest | Sync off | :::caution **OfferDimension** and **OfferPaymentInstallment** keep a 30-day window by default, so an offer created more than 30 days ago reaches Salesforce without its dimension and payment-installment records. Switch both objects to **All** if you need them for your full offer history. ::: ## User Interface Setup ### Enable Fours Widget on Opportunity Pages Add the **Suger Opportunity Quick Panel** component to enable Fours features directly on opportunity records. For more details, see [Add Fours widgets and buttons to Salesforce pages](/salesforce-app/salesforce-app-page-components/). 1. Open Salesforce Setup → Object Manager → Opportunity → Lightning Record Pages. 2. Edit the **Opportunity Record Page**. 3. In the Components panel, search for Suger. > Suger component search results in Lightning App Builder 4. Drag and drop **Suger Opportunity Quick Panel** onto the page layout. > Dragging the Suger Opportunity Quick Panel onto the page layout 5. Save and activate the page. When configured, users will see New Offer and Co-sell buttons on Opportunity records. ### Assign User Permissions Your team will only see the correct Fours buttons if they are assigned the right Permission Set. Fours provides three permission sets: | Permission Set | Visible Features | Typical Use Case | | ---------------------------- | ---------------------------------------------- | ------------------------------------------ | | **Suger User – Marketplace** | Marketplace buttons only (e.g., **New Offer**) | Sales team managing offers | | **Suger User – Cosell** | Co-sell button only | Business development team | | **Suger User** | All functionalities | Power users, admins, or full-feature users | Example: If a user is assigned Suger User – Cosell, they will only see the Co-sell button in the Fours Widget. > Co-sell button visible in the Suger widget for Cosell users #### Custom Permissions Under the hood, button visibility is controlled by the following Custom Permissions (under the Suger namespace). For more details, see [Fours custom permissions in Salesforce](/salesforce-app/salesforce-app-custom-permissions/). - `Create Offer` - `Create Referral` ### Co-sell Field Mapping Link Salesforce fields (such as Amount or Close Date) to partner fields (such as Expected Revenue or Target Close Date) so co-sell referrals carry the right values. For more details, see [Configure Co-Sell Settings for Salesforce](/cosell/cosell-configuration/). ## Authentication & Security Fours connects to your Salesforce org via the **OAuth 2.0 Authorization Code flow with PKCE**, with Refresh Token Rotation, 30-day idle TTL, and IP allowlist enforced at the External Client App level. See [**Salesforce App → Authentication & Security**](/salesforce-app/salesforce-app-authentication-security/) for the full reference — OAuth flow, token storage, required admin policy settings, revocation, and transport security. The Salesforce card in **Settings → Integrations** also reports when its stored credential has stopped working — for example after a refresh token is revoked in Salesforce, or the connection sits idle past its TTL. See [Connection health](/integrations/#connection-health). ### Reconnect the integration When the Salesforce connection stops working — for example after its refresh token is revoked, or after you tighten OAuth policy in Salesforce — reconnect it instead of deleting it. **Reconnect** runs Salesforce OAuth again for the existing integration and replaces only its stored credential; the offer-lookup map, backfill configuration, approvals, and enrichment settings are kept. 1. Go to [Integrations](https://console.suger.io/settings?tab=integrations) in Fours Console, open the **⋯** menu on the verified Salesforce card, and click **Reconnect**. 2. The confirmation dialog names the Salesforce user the integration is connected as. Plan to sign in as **that** user — otherwise Salesforce may simply reuse whichever session your browser already holds. 3. Leave **Change the connected Salesforce user** unchecked — it starts unchecked every time — unless you mean to move the integration to a different Salesforce user (see below). Click **Reconnect**. 4. Salesforce opens in a new window and asks you to sign in again, with the connected username already filled in. Sign in and approve access. The window closes and the console confirms **Salesforce reconnected successfully**. ```d2 direction: down start: "Reconnect confirmed" signin: "Salesforce sign-in\nforced, username pre-filled" same: "Signed in as the user the\nintegration is connected as?" { shape: diamond } optin: "Change the connected\nSalesforce user checked?" { shape: diamond } kept: "Credential replaced\nsettings kept" moved: "Integration now runs as the new user\nsettings kept" refused: "Reconnect cancelled\nnothing changes" start -> signin -> same same -> kept: "yes" same -> optin: "no" optin -> moved: "yes" optin -> refused: "no" ``` #### If you sign in as a different Salesforce user Fours compares the account you signed in with against the one the integration is connected as, ignoring letter case and surrounding spaces. If they differ and **Change the connected Salesforce user** was not checked, Fours cancels the reconnect before touching anything — the integration keeps running as the original user, on its existing credential. The error names both accounts and stays on screen until you dismiss it: > Reconnect cancelled: this integration is connected as {connected user}, but you signed in as {your user}. Sign out of Salesforce (or use a private window) and reconnect as {connected user}. To intentionally run the integration as {your user}, re-run Reconnect and check "Change the connected Salesforce user". To move the integration to another Salesforce user on purpose — a new dedicated integration user, or because a sandbox refresh or a domain change renamed the original — run **Reconnect** again with **Change the connected Salesforce user** checked. Fours then does not pre-fill the connected username, so you can sign in with the new account. Record ownership and permissions follow the new user. :::note - In an org that signs in through SSO, whether Salesforce actually asks for credentials again depends on your identity provider's session policy. The user check above applies either way. - An integration connected before Fours recorded the connected username shows neither the user nor the checkbox in the dialog, and its reconnect is not checked. That reconnect records the user you sign in as, so later reconnects are checked. ::: ## CRM Enrichment Automatically populate Salesforce records with intelligence signals from Fours (engagement scores and marketplace metrics across AWS, Azure, GCP). See [**Salesforce App → CRM Enrichment**](/salesforce-app/salesforce-app-crm-enrichment/) for the full configuration guide — custom field setup, SOQL targeting, refresh-cycle controls, and sync progress tracking. ## Package Fields and Sync Behavior The fields below ship with the **Fours managed package**. If your Salesforce org is on an older package version they do not exist in your schema yet — and because Fours [skips fields that are missing rather than failing the record](#when-something-fails), the rest of your sync keeps working while these values silently never appear. **Upgrading the Fours managed package is therefore a prerequisite for the data in this section.** See [Install the Salesforce App](/salesforce-app/salesforce-app-install/) for the upgrade path. ### Recently added fields All field names below carry the `Suger__` namespace in your org (for example `Suger__Entitlement__c.Suger__AWS_License_ARN__c`). | Object | Field | What it carries | | --- | --- | --- | | `Entitlement__c` | `AWS_License_ARN__c` | The AWS license ARN for the entitlement. Written **only** for AWS entitlements that actually have a license ARN — it stays empty for Azure and GCP entitlements, and for AWS entitlements with no ARN. An empty value is normal, not a sync failure. | | `Referral__c` | `PRM_Partner_ID__c` | The Fours PRM partner associated with the referral, so partner-sourced referrals can be reported on in Salesforce. | | `Offer__c` | `Partner_ID__c` | The Fours partner associated with the offer. | | `Entitlement__c` | `Partner_ID__c` | The Fours partner associated with the entitlement. | | `Contact__c` | `Contact_ID_CS__c` | A second external ID on the contact — see [How Fours matches contacts](#how-fours-matches-contacts) below before you build anything on it. | | `Offer__c` | `AWS_Net_Payment_Term__c` | The AWS net payment term agreed on the offer, so payment terms are reportable in Salesforce alongside the rest of the offer. | | `Entitlement__c` | `AWS_Net_Payment_Term__c` | The accepted AWS net payment term for the entitlement, in the same format as the `Offer__c` field above: `Net 15`, `Net 30`, `Net 45`, `Net 60`, `Net 90` or `Net 120` — or `Maximum Net` plus the days (for example `Maximum Net 60`) when the entitlement's offer is a resale authorization (CPPO). Written **only** for AWS entitlements and re-derived on every sync: Fours clears it when the entitlement has no term on record or the term is not one of those six, so an empty value means Fours has no valid accepted AWS payment term to sync. It is not on the shipped Entitlement page layouts — add it to yours, or use it as a column or filter in the **Cloud Entitlements (Suger)** and **Suger Entitlements and Revenue Records** report types. | | `Referral__c` | `AWS_InvitationMessage__c` | The message that accompanied an AWS engagement invitation, so the context an AWS seller sent with a referral is visible on the record rather than only in Partner Central. | | `Funding__c` | `AWS_CashRequest_PurchaseOrderNumber__c`, `AWS_CashRequest_AccountProfileId__c` | The purchase order number AWS issued for a cash request, and the Payee Central account profile the cash is paid to. | | `Funding__c` | `AWS_AceOpportunityId__c`, `AWS_AwsAccountId__c`, `AWS_PartnerContactEmail__c` | The ACE opportunity and AWS account on the request, and your partner contacts' emails (`;`-joined). | | `Funding__c` | `AWS_FulfillmentTypes__c`, `AWS_IssuedAmount__c`, `AWS_ExpirationDate__c`, `AWS_IsvWmpSecondTrancheConsentCaptured__c` | How the funding is fulfilled, the amount AWS issued, when it expires, and the ISV Workload Migration second-tranche consent. See [Funding__c](/salesforce-app/salesforce-app-custom-objects/#funding__c) for every funding field. | | `FundingCashClaim__c` | `AWS_BenefitApplicationId__c` | The fund claim ID. The claim's start, end and due dates now sync as well, once AWS records them. | ### AWS Partner Central leads Fours now backfills **AWS Partner Central leads** into their own object, `Suger__Lead__c`, on the same schedule as the other objects. A lead is the pre-opportunity signal AWS shares with you; keeping it in Salesforce means you can route, report on, and follow up leads in the same place as the referrals they become. Each record carries: | Group | What it holds | | --- | --- | | **Identity** | The Fours lead ID (the external ID used to match the record on each sync), the AWS-side external, invitation, and context identifiers, and a link to the Fours partner. | | **Lifecycle** | Invitation status, qualification status, overall status, and the expiration date after which the lead can no longer be acted on. | | **Company and fit** | Company name, industry, website, country, market segment, and AWS maturity. | | **Customer contact** | First name, last name, email, job title, and phone number for the contact AWS shared. | | **Location** | City, state, and postal code. | | **Scoring and history** | A readiness score, and the interaction history recorded against the lead. | | **Conversion** | The converted opportunity identifier, plus a lookup to the `Referral__c` record the lead became. | :::note **The converted-referral lookup fills in on a later run.** A lead's link to its `Referral__c` record stays empty until that referral has itself been backfilled to Salesforce. It is populated on a subsequent scheduled backfill — an empty lookup on a freshly synced lead is expected, not a failure. ::: :::caution Like every field in this section, the lead object ships with the **Fours managed package**. If your org is on an older package version, `Suger__Lead__c` does not exist in your schema and leads simply do not appear; the rest of your sync is unaffected. Upgrade the package to start receiving them. ::: ### Partner contact associations The partner contacts Fours backfills as `Contact__c` records — the AWS, Azure, GCP, or Fours partner sellers mapped to your accounts — now also get **one row per association**, in two objects that ship with the managed package, so you can report on which partner sellers are tied to which accounts and opportunities. | Object | One row per | Parents | | --- | --- | --- | | `Contact_Account__c` — **Partner Contact Account (Suger)** | Partner contact and each Account it is mapped to, including accounts with no open opportunities | `Contact__c` (master-detail), `Account` (lookup) | | `Contact_Opportunity__c` — **Partner Contact Opportunity (Suger)** | Partner contact and each Opportunity on the accounts it is mapped to | `Contact__c` (master-detail), `Opportunity` (lookup) | ```d2 direction: right contact: "Contact__c\npartner contact" ca: "Contact_Account__c\nPartner Contact Account (Suger)" co: "Contact_Opportunity__c\nPartner Contact Opportunity (Suger)" account: "Account" opp: "Opportunity" contact -> ca: "master-detail" contact -> co: "master-detail" ca -> account: "lookup" co -> opp: "lookup" account -> opp: "each opportunity on\na mapped account" { style.stroke-dash: 4 } ``` Both objects carry the same columns, so one report shape works for either: | Field | What it carries | | --- | --- | | **Link Source** | How the association arose: `Referral` (actual referral activity), `Predicted` (matched to the account by email domain — inferred, not confirmed), or `Upload` (an admin mapped it by CSV). It shows the association's current state and never downgrades: Predicted → Upload → Referral. | | **Partner** | The cloud partner the contact belongs to: `AWS`, `Azure`, `GCP`, or `Suger`. | | **Contact Name**, **Contact Email**, **Contact Role** | Copied from the partner contact, so Account- and Opportunity-based reports can show them. | | **Last Referral Time** | The contact's most recent referral for the account. Empty on `Predicted` associations. | | **Collaboration Score** | `Contact_Account__c` only: the contact's collaboration score for the account, 0–100. Blank until Fours has scored the pair. | | **Suger Contact ID** | Fours' own contact ID, for joining back to Fours from a data warehouse. | | **Last Seen** | When a backfill last confirmed the association. Refreshed at least every 7 days. | **Reports.** The package adds the report type **Accounts with Suger Partner Contacts** and, built on it, the ready-made **[Suger] Partner Contacts by Account** report in the **Suger Reports** folder. Group or filter on **Link Source** to separate confirmed referral activity from inferred domain matches. The report types **Opportunities with Suger Partner Contacts**, **Suger Partner Contact Accounts**, and **Suger Partner Contact Opportunities**, and the **[Suger] Partner Contacts by Opportunity** report built on the first, are no longer installed with the package: every packaged custom report type counts against your org's custom report type limit, and orgs already at that limit could not upgrade. An org that installed them earlier keeps them; new installs do not get them. See [Partner Contact Report Types](/salesforce-app/salesforce-app-reports/#partner-contact-report-types). **How the rows stay current.** The **Contact** backfill writes these rows right after the contacts themselves, so they follow the Contact setting under [Choose What Backfills to Salesforce](#choose-what-backfills-to-salesforce). When an association ends, its row is deleted on a later pass, so a contact is not reported against an opportunity it no longer relates to. When Fours cannot confirm an association — for example because the Integration User can no longer see the Account or Opportunity — it keeps the row rather than delete it. Rows for a contact that is no longer one of Fours' partner contacts are removed once no pass has confirmed them for 30 days. Fours manages these rows, so hand edits are overwritten on the next pass. :::caution Like the other fields in this section, both objects ship with the **Fours managed package**. In an org on an older package version they do not exist: Fours skips the association rows and the contact backfill carries on unaffected. Upgrade the package to start receiving them. Salesforce reports an object the Integration User is not allowed to see the same way as a missing one, so if the rows never appear on a current package, check the Integration User's permission sets: the **Suger Integrator** permission sets give it the create, edit, and delete access the backfill needs, and the Fours user permission sets — including **Suger User**, **Suger User - Marketplace**, **Suger User - Cosell**, and **Suger User - Read Only** — give your team read access for reporting. ::: ### Sync behavior notes **Funding data follows the FundingRequest backfill.** The funding fields above reach Salesforce only while the **FundingRequest** backfill is on, and it is off by default — see [Choose What Backfills to Salesforce](#choose-what-backfills-to-salesforce). **AWS Annual Run Rate** is now also filled for ISV Workload Migration requests. **A funding record's Referral lookup now fills in.** The FundingRequest backfill sets the **Referral** lookup on `Funding__c` to the AWS referral that shares the funding request's Salesforce Opportunity, matching the Opportunity ID whether it is stored in its 15- or 18-character form. When that Opportunity has more than one AWS referral, Fours neither sets nor updates **Referral**, so any value already there stays. The **Opportunity** lookup is unaffected. Existing funding records pick up the lookup on the next FundingRequest backfill, and so does the **Referral** column in reports built on the **Suger (Fundings)** report type. **AWS Account ID fills in when Fours holds no AWS agreement.** On AWS `Entitlement__c` records, **AWS Account ID** (`AWS_Account_ID__c`) and **Buyer Account ID** (`Buyer_Account_ID__c`) come from the AWS agreement's acceptor. When Fours has no agreement stored for an entitlement, both now fall back to the linked buyer's AWS account ID instead of staying blank, and entitlements that showed them blank fill in on the next backfill. An entitlement with no linked buyer still leaves them blank. **Offers linked in bulk.** When you [bulk link offers to Salesforce records](/console/private-offers/#bulk-link-offers-to-salesforce-records), each link reaches the offer's `Offer__c` record on the next scheduled backfill while **Offer** sync is on — or as soon as the import finishes, if you leave **Backfill to CRM right away** on. If your **Offer** backfill uses **Days Back**, the scheduled backfill never reaches offers created before that window, so leave the option on for them. - The **Opportunity**, **Quote**, **Account**, **Buyer**, **Product** and **Created By** lookups keep their usual sync. A link on one of them is not a one-time write, and the overwrite warning above still applies. - A link that bulk link writes to any other lookup is written once. After Salesforce accepts it, Fours stops sending it, so a later edit — or a value you clear — in Salesforce stays. - A link whose record no longer exists, or whose field the Integration User can't edit, is skipped and tried again on the next backfill. The rest of the offer still syncs. **Entitlement name and dates now follow the latest term.** `Entitlement__c`'s **Name**, **Start Date** and **Creation Date** reflect the **latest** entitlement term and its linked offer, rather than the original one the entitlement was created from. This fixes renewed entitlements showing stale values. :::caution This changes existing records. After a renewal, an entitlement's Name, Start Date and Creation Date **will change** to the renewal's values on the next backfill. If you have reports, list views, or automation that assume Start Date is the *original* subscription start, revisit them — that date now moves when the customer renews. ::: **Products not yet listed on a marketplace are skipped, not fatal.** A product with no external ID (because it has not been listed on a marketplace yet) is now skipped during backfill. Previously it aborted the whole backfill with a required-field error, so a single unlisted product could block every other object from syncing. **Partner-to-partner co-sell referrals are included in the periodic backfill.** Fours partner-to-partner co-sell referrals now sync on the regular 4-hourly backfill, not only when a single record is synced on demand. If you were re-syncing these by hand, you no longer need to. **Auto-share criteria can filter on a child object.** Auto-share criteria that reach across to a related object — for example narrowing to opportunities that contain a particular Opportunity Product — now work. Previously a criteria of that shape failed the whole auto-share run, so a single cross-object condition stopped every opportunity from being shared, not just the ones it described. Nothing about how you write criteria changes, and a criteria that already worked keeps behaving identically. See [Auto-Share Referrals](/cosell/cosell-configuration/#auto-share-referrals) for the Builder, the Advanced (SOQL) tab, and **Preview matches**. **AWS revenue-record payment terms follow the accepted AWS term.** On AWS revenue records, `RevenueRecord__c.Payment_Terms__c` now carries the net payment term accepted on the AWS agreement whenever one is known — even when the invoice date or payment due date is missing, or the gap between them differs from that term. Records without an accepted term, and all non-AWS records, still derive `Net N` from the invoice date to the payment due date. A value synced earlier can change when the record next syncs. Revenue records reach Salesforce only while **RevenueRecord** sync is on — see [Choose What Backfills to Salesforce](#choose-what-backfills-to-salesforce). **GCP dates now match the Google Cloud Marketplace day.** The **Start Date** of a GCP `Entitlement__c`, and the **Contract Start Time** and **Contract End Time** Fours derives for GCP `Offer__c` records synced from Google Cloud Marketplace, now use the calendar day the GCP portal shows (US Pacific time) instead of the UTC date. Before, an offer accepted late in the Pacific day could show the following day in Salesforce. - When Fours corrects an active GCP entitlement's end date to match its offer's term, the new **End Date** is pushed to Salesforce right away instead of waiting for the next scheduled backfill. - A GCP offer that starts on acceptance and has not been accepted yet now shows a **Contract End Time** with a blank **Contract Start Time**. That end reflects the term Google reports for the pending offer and can change once the customer accepts. :::caution This changes existing records: a GCP entitlement or offer date can move by one day when the record next syncs. If reports, list views, or automation group GCP records by date, check them after the change. ::: ### How Fours matches contacts Fours identifies partner contacts in Salesforce by `Suger__Contact_ID__c`. A second external ID, `Suger__Contact_ID_CS__c` ("Contact ID (Case-Sensitive)"), is also populated with the same value on every sync, but it is **not** used for matching — it is being staged for a future migration. Orgs on an older Fours package that lacks `Suger__Contact_ID_CS__c` sync normally; the field is optional and its absence does not block contact sync. :::note Because `Suger__Contact_ID_CS__c` is not the matching key, do not build deduplication rules, matching rules, or integrations on it yet. `Suger__Contact_ID__c` remains the field that identifies a contact. ::: ## Fours AI Tools Fours AI uses a **middleware** strategy — wrapping the Salesforce REST API directly. > **Org-level only**: Salesforce tools use the org-level integration credentials. | Tool | Description | |------|-------------| | `salesforce_query` | Execute a SOQL query against Salesforce | | `salesforce_search` | Execute a SOSL search across Salesforce objects | | `salesforce_list_objects` | List all available sObject types | | `salesforce_describe_object` | Describe an sObject type (fields, metadata, picklist values) | | `salesforce_get_record` | Get a single record by sObject type and ID | | `salesforce_create_record` | Create a new record | | `salesforce_update_record` | Update fields on an existing record | | `salesforce_delete_record` | Delete a record by sObject type and ID | ## Troubleshooting | Issue | Possible Cause | Resolution | | --- | --- | --- | | "New Offer" button is missing | Permission set or page layout issue | Verify the correct Fours permission set is assigned and force-refresh the browser (Ctrl+Shift+R, or Cmd+R on Mac) | | User sees the wrong button after being assigned a permission set | Salesforce may have auto-enabled extra custom permissions during package install | Check the user's profile for unnecessary custom permissions under the Suger namespace and uncheck them | | Fours can't read or sync certain records | Missing Read/View All access on Account, Contact, Opportunity, or mapped fields | Confirm Field-Level Security and object permissions on the Integration User's permission set | | Integration User can't log in or perform expected actions | Salesforce Integration License is API-only | Business users need a full Salesforce License and the correct permission set, not the Integration License | | "Reconnect cancelled: this integration is connected as …" | You signed in to Salesforce as a different user than the one the integration runs as, and did not opt in to changing it | Sign out of Salesforce (or use a private window) and reconnect as the named user. If the change is intended, re-run **Reconnect** with **Change the connected Salesforce user** checked. See [Reconnect the integration](#reconnect-the-integration) | | "Copy Offer URL" does nothing | Cloud marketplace latency | AWS or Azure can take 3–5 minutes to generate a URL. Wait and refresh. | | `STORAGE_LIMIT_EXCEEDED` | Sync logs are filling a Sandbox | Delete sync logs via the Fours Console, or set a shorter log retention period in Settings | | Products not visible in the Salesforce Suger app | Sync hasn't been triggered yet | Go to the Products tab in the Salesforce Suger App and click Refresh | ## Frequently Asked Questions **How long does the integration take?** A standard setup typically takes 10–15 minutes. **What authentication method does Fours use to connect with Salesforce?** OAuth 2.0 Authorization Code flow with PKCE, through a dedicated Integration User. Fours never requires or stores a username and password. **Can we create Agreement-Based Offers (ABO) from Salesforce?** Yes, directly within the Salesforce widget. **Will ACE referrals show up in Salesforce?** Yes. Referrals submitted from the Salesforce widget link automatically to the Opportunity. Referrals submitted from the Fours Console can be linked manually by adding the connected Opportunity ID. Referrals submitted directly from ACE can also be found and linked manually in Salesforce. **Does Fours edit our native objects, like Opportunities or Accounts?** No. The Fours managed package only creates custom objects it manages (Offers, Referrals, Entitlements, Contacts, etc.). Fours only edits native objects if explicitly given write access for a specific purpose, such as writing engagement scores to an Account or offer details back to an Opportunity. **How do I map standard, custom, or CPQ fields to Fours private offer fields?** Configure field mappings in the Fours Console under your Salesforce Integration settings. Fours supports one-to-one mappings, picklist value mappings, and an Expression Mode (SOQL) for conditional logic. If your mapping involves CPQ quotes (`SBQQ__Quote__c`), the Integration User needs both a standard Salesforce License and a CPQ license. **Why can't Fours see or sync certain opportunities?** Fours' visibility is entirely determined by the Integration User's sharing rules and permissions. Confirm the Integration User's permission set grants Read and View All access to Account, Contact, and Opportunity, plus any mapped custom fields. **How do I set up separate Sandbox and Production environments?** Create separate integrations for each. In Fours Console, create a dedicated testing organization, then check the Sandbox box and enter your Sandbox subdomain when configuring that integration. **Can I build reports combining Salesforce Opportunities with Fours offer and referral data?** Yes. Fours syncs marketplace data into custom objects like `Offer__c`, `Referral__c`, and `Entitlement__c`. Create Custom Report Types (for example, "Opportunities with Fours Offers") to report on this data. Due to standard Salesforce reporting limits, Referrals and Entitlements can't be joined in a single report — use two separate reports. **How do I protect standard fields, like Stage Name, from being overwritten during sync?** Use Salesforce validation rules to restrict edits on the field, or map the incoming data to a read-only custom field instead. ## Removing the Integration To completely remove the Salesforce integration: ### From Fours Console 1. Navigate to **Fours Console** → **Settings** → **Integrations** → **Salesforce** 2. Click the 🗑️ **Delete** button 3. This removes stored credentials from Fours ### From Salesforce 1. Go to **Setup** → **Connected Apps OAuth Usage** 2. Locate the **Suger Connected App** 3. Click the **User Count** link 4. Click **Revoke** (specific user) or **Revoke All** (all users) :::note If the User Count shows 0, the integration has already been fully revoked. ::: --- Source: https://doc.fours.com/integrations/servicenow/ # ServiceNow Connect ServiceNow so Fours AI can work with your incidents, change requests, and service catalog. --- ## Overview [ServiceNow](https://www.servicenow.com) is an IT service management platform covering incidents, problems, change management, and a service catalog. Connecting it lets the Fours AI agent read and act on your ITSM records from a Fours workflow or chat. ### Org-Level vs User-Level > **Org-Level**: Supported, using the OAuth 2.0 client-credentials grant against your own ServiceNow instance. > > **User-Level**: Not currently available. ServiceNow's OAuth client must be registered inside your own instance rather than centrally, so there is no single Fours app your users could sign in to. Supporting per-user connections would mean each user's sign-in borrowing your instance's client — a dependency Fours does not yet model. ### How the connection works The OAuth client is registered in **your** ServiceNow instance, and Fours acts as the OAuth Application User you attach to it. Fours exchanges the client ID and secret for an access token against your instance and re-mints it as needed — there is no Fours-owned ServiceNow app, because the authorize endpoint is per-instance. ```d2 shape: sequence_diagram admin: "Your ServiceNow admin" snow: "Your ServiceNow instance" suger: "Fours" agent: "Fours AI agent" admin -> snow: "Enable the client-credentials grant property" admin -> snow: "Create an OAuth Application User, then an inbound OAuth client" admin -> suger: "Client ID + Secret, instance host" agent -> suger: "Run a ServiceNow tool" suger -> snow: "client_credentials grant against your instance" snow -> suger: "Access token (~30 min, no refresh token) — Fours re-mints it" { style.stroke-dash: 4 } suger -> snow: "Table / Catalog / Attachment call, acting as the Application User" snow -> agent: "Incidents, problems, changes, approvals, catalog" { style.stroke-dash: 4 } ``` ## Create Integration (Org-Level) ### Prerequisites - **Washington DC release or later.** Earlier releases do not support the client-credentials grant at all. - The system property `glide.oauth.inbound.client.credential.grant_type.enabled` set to `true`. - An **OAuth Application User** on the OAuth record. Fours acts as this user, so its roles set the ceiling on everything the integration can do. Grant it the **`itil`** role at minimum; a few operations additionally need **`admin`** (see [Fours AI Tools](#fours-ai-tools)). - Permission to create an application registry entry (typically the `admin` role). - The Fours **Admin** role — connecting, disconnecting, and running an integration's actions are all admin-only in Fours. - A decision on **auth scope enforcement** — see [Auth scope](#auth-scope) below. Fours requests no ServiceNow auth scope, so leaving enforcement on with no scope selected produces a connection that authenticates but cannot call anything. ### Step 1 — Enable the client-credentials grant ServiceNow does not ship this property; you create it. 1. Go to **All → System Properties → All Properties**. 2. Make sure your application scope is **Global** — the property has no effect in a scoped app. 3. Click **New** and enter: | Field | Value | | --- | --- | | Name | `glide.oauth.inbound.client.credential.grant_type.enabled` | | Type | `true | false` | | Value | `true` | | Application | Global | To confirm, filter the list on **Name** *is* that value — you should get exactly one row reading `true`. Filtering with `>=` returns the next property alphabetically instead, which looks like a match but isn't. ### Step 2 — Create the integration user The client-credentials token acts as this user, so its roles are the ceiling on everything Fours can do. Use a dedicated account, never a real person's. 1. Go to **All → User Administration → Users** and click **New**. 2. Set **User ID** to something identifiable, for example `suger.integration`. 3. Set **Identity type** to **Machine**. Leave **Internal Integration User** unchecked — that flag exists to bypass WS-Security on SOAP interfaces and is not what you want here. 4. **Submit**. No password is needed; this account never signs in interactively. 5. Reopen the record. In the **Roles** related list click **Edit**, add **`itil`**, and save. Several inherited roles appear beneath it — that is normal. > The saved integration user record with User ID suger.integration, Identity type set to Machine, Internal Integration User unchecked, and the empty Roles related list below :::info To stop the account being usable for UI sign-in, add **Web service access only** through **Configure → Form Layout** and check it. Optional — the integration works either way — but set it only on the integration user. Checking it on your own admin account locks you out of the instance. ::: ### Step 3 — Register the inbound integration 1. Go to **All → System OAuth → Application Registry** and click **New**. 2. Choose **New Inbound Integration Experience**. The `[Deprecated UI]` entries below it still work, but they hide the OAuth application user field behind **Configure → Form Layout**. > The 'What kind of OAuth application?' chooser, with 'New Inbound Integration Experience' at the top above the outbound and deprecated options 3. In the Machine Identity Console, click **New integration**, then pick **OAuth - Client credentials grant** — "machine-to-machine access to the application without the user's context". > The 'Select your application connection type' dialog listing authorization code, client credentials, JWT bearer, resource owner password, and third-party OIDC options :::warning Do not pick **Authorization code grant** — that is a different Fours connector with a browser redirect, and it is not what this integration uses. **JWT bearer** and **Resource owner password** are also wrong here. ::: 4. Fill in the **Details** section: | Field | Value | | --- | --- | | Name | `Fours` | | Provider name | `Fours` — free text naming the service you are integrating with; it is inventory metadata only and is not read during the token exchange | | OAuth application user | the user from step 2 | | Client ID / Client Secret | generated by ServiceNow — copy both now | | Active | checked | > The Details section of the inbound integration form showing Name, Provider name, OAuth application user, the generated Client ID, and the masked Client Secret :::info If the **OAuth application user** picker cannot find your user, give the record a **First name** and **Last name**. The picker searches the derived display name, not the User ID, so an account with both name fields blank is effectively invisible to it. ::: 5. Set the **Auth scope** section as described below, then save. > The Auth scope section configured as recommended: a scope named suger limited to the Table, Attachment, Service Catalog and Aggregate APIs, with Allow access only to APIs in selected scope checked ### Step 4 — Connect in Fours In the Fours console, open [Settings → Integrations](https://console.suger.io/settings?tab=integrations), click **Connect** on **ServiceNow**, and enter: | Field | Value | | --- | --- | | ServiceNow Domain | your instance host, for example `acme.service-now.com` — host only, no `https://` and no trailing slash | | Client ID | from step 3 | | Client Secret | from step 3 | Fours exchanges the pair for an access token and re-mints it as needed. Client-credentials tokens last about 30 minutes and carry no refresh token, which is expected. :::info The OAuth client belongs to *your* instance. Fours registers nothing on your behalf and holds no ServiceNow client of its own, so deleting or rotating that registry entry immediately breaks the connection. ::: ## Auth scope On releases with the Machine Identity Console, the inbound-integration form has an **Auth scope** section, and its **Allow access only to APIs in selected scope** checkbox is **enabled by default with no scope selected**. Saved in that state, the integration authenticates successfully and then returns 403 on every call, because a token with no scope matches no scope-listed API. Two supported configurations. Prefer the first — it is verified to work and avoids ServiceNow labelling the client **Broadly scoped**. ### Scope the client to the APIs Fours uses Click **Create auth scope**, name it `suger`, then in **Limit authorization to the following APIs** — a multi-select of registered API definitions, not URL paths — add: | API definition | Why Fours needs it | | --- | --- | | **Table API** | incidents, problems, change requests and tasks, groups, users, approvals, knowledge, and catalog *records* — everything under `/api/now/table/` | | **Service Catalog API** | `get-catalog-item` and `order-catalog-item`, which use `/api/sn_sc/servicecatalog/` rather than the Table API | | **Attachment API** | `list-attachments` | | **Aggregate API** | not used by any tool today. Include it so counting and grouping tools do not require a scope revision later | Leave **Allow access only to APIs in selected scope** checked, and save. Create a dedicated scope rather than extending an existing one. ServiceNow warns that editing a scope's API list affects every client sharing it — a scope used only by Fours keeps later revisions safe. :::info Fours mints its token without a `scope` parameter, and ServiceNow supplies the client's configured scope by default — so this works without Fours requesting `suger` by name. Confirm it on your instance after saving by minting a token (see [Troubleshooting](#troubleshooting)): the response's `scope` should echo your scope name, and a test read should return records. If `scope` comes back empty or reads return 403, use the fallback below and tell Fours support. ::: ### Fallback: turn enforcement off Uncheck **Allow access only to APIs in selected scope**. Access then falls back to the acting user's access controls and API policies, which is the model this connector was built around — the `itil` role on the OAuth Application User is the ceiling. ServiceNow labels the client **Broadly scoped** in this state and flags it in the Machine Identity Console's security findings. That is accurate: the role is the only boundary. It remains the configuration Fours is known to work with, so choose it deliberately rather than as an oversight, and keep the acting user's roles as narrow as your tools require. :::warning Do not satisfy the checkbox with the **`useraccount`** scope instead. It grants everything the signed-in identity can reach — no narrower than turning enforcement off, but it *looks* restricted, which is worse than being honestly unscoped. ServiceNow's own form flags it as not recommended. ::: ## Troubleshooting | Symptom | Cause | | --- | --- | | `unsupported_grant_type` when minting a token | The `glide.oauth.inbound.client.credential.grant_type.enabled` property is missing or not in **Global** scope | | Token mints, but every tool returns 403 | Auth scope enforcement is on with no matching scope — see [Auth scope](#auth-scope) | | Some tools work, user/group writes 403 | The OAuth Application User has `itil` but not `admin` | | `invalid_client` | Client ID and secret do not match the registry entry | To check the ServiceNow half on its own, before involving Fours: ```bash curl -s -X POST 'https://YOUR_INSTANCE.service-now.com/oauth_token.do' \ -d 'grant_type=client_credentials' \ -d 'client_id=YOUR_CLIENT_ID' \ -d 'client_secret=YOUR_CLIENT_SECRET' ``` ## Fours AI Tools When ServiceNow is connected, the Fours AI agent can work your ITSM records through Fours' built-in tools (40 actions). > **Org-level**: Every tool runs as the instance's **OAuth Application User**. If a tool returns a permission error, that user is missing a role — start with `itil`. | Capability | What the agent can do | |------------|-----------------------| | **Incidents** | Create, read, update, delete, and list incidents (e.g. `create-incident`, `update-incident`, `list-incidents`) | | **Problems** | Create, read, update, delete, and list problem records (e.g. `create-problem`, `list-problems`) | | **Change management** | Full create/read/update/delete on change requests and change tasks (e.g. `create-change-request`, `update-change-task`) | | **Approvals** | List approvals and record an approval decision (`list-approvals`, `update-approval`) | | **Service catalog** | Browse catalog items, read a request and its items, and place an order (e.g. `list-catalog-items`, `order-catalog-item`) | | **Knowledge base** | Read and list knowledge articles (`get-knowledge-article`, `list-knowledge-articles`) | | **Users & groups** | Create, read, update, delete, and list users and groups (e.g. `create-user`, `update-group`) | | **Any table** | Read or list records from an arbitrary table for cases the typed tools don't cover (`get-table-record`, `list-table-records`) | | **Attachments** | List attachments on a record (`list-attachments`) | :::warning Creating and deleting users and groups requires the `admin` role on the OAuth Application User, not just `itil`. Grant `admin` only if you intend the agent to perform those operations. ::: :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration Editing is not supported. To rotate the client secret or point Fours at a different instance, delete the integration and create it again. ## Delete Integration Click the 🗑️ button next to **ServiceNow** in the **Integrations** list. The stored client pair is destroyed with the integration record. Delete the application registry entry in ServiceNow too if you want to revoke access from that side. --- Source: https://doc.fours.com/integrations/slack/ # Slack Receive instant Fours notifications and alerts in your Slack workspace, and chat with Fours AI there. --- :::info Fours was formerly named Suger. In Slack, the app and its bot — the name you invite with `/invite @Suger`, the name you @mention in a channel, and the sender of every notification and Fours AI reply — still use the name Suger until the app is renamed. ::: ## Overview By connecting with Suger app for Slack in your Slack workspace, you and your team can get instant notifications & alerts as soon as possible if any important sales operations are happening cross your cloud marketplaces. The same installation lets your team chat with Fours AI from Slack — see [Chat with Fours AI in Slack](#chat-with-fours-ai-in-slack). ### Org-Level vs User-Level - **Org-Level**: One shared workspace installation for the whole organization. Fours posts as the **Suger bot**, and this is what drives the notification and alert configuration described below, and what lets your team [chat with Fours AI in Slack](#chat-with-fours-ai-in-slack). An administrator connects it once under **Settings → Integrations**. - **User-Level**: You connect Slack as **yourself** under **User Integrations**. Fours mints a user token alongside the bot token, so when Fours AI sends a Slack message on your behalf it is posted **as you** — your name and avatar — rather than as the Suger bot, and when it reads or searches Slack it sees only what you can see. Looking up workspace members still runs on the bot token issued alongside it. The user-level connection requests these Slack user scopes: | Scope | What it allows | |-------|----------------| | `chat:write` | Post messages as you, in channels and conversations you can already post to. | | `channels:read` | Look up public channels by name so a destination can be resolved from what you typed. | | `groups:read` | Look up the private channels you are a member of. | | `im:write` | Open a direct-message conversation so a message can be sent to a person. | | `channels:history` | Read messages in public channels. | | `groups:history` | Read messages in the private channels you are a member of. | | `im:history` | Read your direct messages. | | `mpim:history` | Read your group direct messages. | | `search:read` | Search messages across the conversations you can see. | A Slack connection keeps the scopes it was granted when you connected. If Fours AI can't read or search Slack for you, your connection predates those scopes: open your Slack card's **⋯** menu under **User Integrations**, choose **Details**, and click **Reconnect** to grant them. :::info The two levels are independent. Connecting Slack as a user does not change or replace your organization's notification installation, and you do not need a user-level connection to receive Fours notifications. You do need one for the Fours AI assistant to use Slack on your behalf — see [Fours AI Tools](#fours-ai-tools). ::: ## Create Integration In your [Fours Console Integration](https://console.suger.io/settings?tab=integrations), find the **Slack** card among your organization's integrations. Only an administrator can connect it. 1. Click **Connect** on the Slack card, then click **Start connection** in the **Connect Slack** dialog. Slack's authorization page opens in a new window; if you are not yet signed in to your Slack workspace, Slack asks you to sign in first. 2. Slack asks you to allow the Suger app for Slack to access your workspace. You must pick a Slack channel (e.g. #suger-alerts), created ahead of time, to receive Fours notifications in. Click the `Allow` button: > Allow button for Suger Slack app permissions 3. Back in Fours, the dialog shows **Slack is connected.** Click **Close**. The Slack card now shows a green check. 4. Optional: to check that messages reach your channel, open the card's **⋯** menu and click **Verify**. Your Slack channel receives a verification message from the Suger app. ```d2 shape: sequence_diagram admin: "Your Fours admin" fours: "Fours" slack: "Slack" admin -> fours: "Slack card: Connect, then Start connection" fours -> slack: "Open Slack's authorization page" admin -> slack: "Pick the notification channel, click Allow" slack -> fours: "Workspace, bot and default channel" { style.stroke-dash: 4 } fours -> admin: "Slack is connected." { style.stroke-dash: 4 } admin -> fours: "Optional: Verify" fours -> slack: "Verification message to that channel" ``` To see which workspace is connected, open the card's **⋯** menu and choose **Details**. The **Workspace** section reads the workspace live from Slack: its name, its Slack domain, and the account the app is connected as. :::warning - If you choose a **private channel** for Fours notifications or set it to private after integrating, you must invite the `Suger app` to the channel; otherwise, the `Suger bot` won't be able to send messages — notifications will fail silently. - To invite the app, open the private channel in Slack and type `/invite @Suger`. How to invite `Suger app` to the **private channel** is also shown below. ::: > Inviting Suger app to a private Slack channel ## Configure Notification An administrator changes where notifications go: open the Slack card's **⋯** menu and click **Edit**. The dialog also shows the **Channel** your installation posts to by default and the **Scope** the Suger app holds in your workspace. When Fours needs a Slack scope your installation was not granted, the Slack card shows an orange alert, and the **Edit** dialog lists the missing ones under **New scopes need to be authorized**. To grant them, open the card's **⋯** menu, choose **Details**, click **Reconnect**, and authorize the app again in Slack. Reconnecting keeps your notification settings. You are allowed to edit the notification configurations below: - **Enable Notification**: Enable or disable the notification in the Slack channel by toggling the switch. Use this master toggle to pause or resume all Slack alerts instantly. - **Notification Scope Configs**: You can configure the notification scopes and their corresponding destination slack channels, so specific alerts can go to different teams. For example, route `CREATE` actions to `#sales-wins` and `CANCEL` actions to `#customer-success`. To add a new scope, click `Add notification scope`. >Add notification scope form for Slack channels ## Fours AI Tools Beyond the notification channel described above, a connected Slack workspace also gives Fours AI a set of Slack capabilities. Fours AI can: | Capability | What it does | |------------|--------------| | **Send a message** | Post a message to a channel, a private channel, or as a direct message to a person. You can give a channel name (`#sales-wins`), a channel id, or a person — Fours resolves it to the real destination before sending. | | **Find channels** | Search the workspace for channels whose name contains what you typed, so you can say "post this in the deals channel" without knowing its id. | | **Look up one channel** | Given a channel id, return which channel it actually is — its name, whether it is private or archived, its topic and purpose, and whether the connected Slack account is a member. Fours uses this to tell you the channel **name** before it posts to an opaque id, and to warn you when a send would fail because the account has not joined that channel. | | **Find a person** | Look up workspace members by email address, or by part of their handle, real name, or display name, so a message can be addressed to a person rather than to a channel. Every match is returned rather than a single guess — if more than one person matches, Fours asks you which one it should use. | | **Read a conversation** | Read the recent messages in one channel, private channel or direct message — or the replies in one thread — to answer "what did we decide in #pricing?". It returns up to 200 messages at a time, not the whole history. | | **Search messages** | Search every conversation the connected Slack account can see, using Slack's own search modifiers such as `in:#channel`, `from:@person`, `before:` and `after:`. Each match links back to its message. Needs a user-level connection. | Which Slack connection these use depends on whose agent is running, never on which connections happen to exist. The Fours AI assistant and agents you own use only **your user-level** Slack connection: messages post **as you**, and reading and searching see only what you can see in Slack. Without a user-level connection, they have no Slack capabilities at all. Org-level agents use the **org-level** installation and post as the Suger bot; they cannot search messages. See [User-Level vs Org-Level Agents](/insulin/agents/#user-level-vs-org-level-agents). :::warning[Sending waits for your approval — where you can answer] When you chat with Fours AI in the console's main conversation, in a Slack direct message, or by mentioning the app in a Slack channel or thread, **every Slack message it wants to send waits for your decision.** You see the destination and a preview of the text, and nothing is posted until you allow it; denying it stops the send. In Slack the request arrives as an approval card that only you can answer. If nobody answers within three minutes, the send lapses and nothing is posted. Finding channels, looking up a channel or a person, reading and searching are not gated. Because an id like `C0123ABCD` tells a person nothing, Fours AI names the channel behind an id before it asks you, and the request itself flags a destination given only as an id so you can check it. The approval needs someone who can answer it, so it is not a guarantee everywhere. A Slack message sent from a job, by an agent in an Insulin channel, from a reply inside a sub-thread in the console, or from a Microsoft Teams chat goes out without waiting. See [Tool Approvals](/insulin/agents/#tool-approvals). ::: If a send is approved but the destination is a private channel the connected account has not joined, Slack rejects it (`not_in_channel`) and Fours reports the failure — it never reports a silent success. Invite the account to the channel and try again. ## Chat with Fours AI in Slack Your organization's Slack installation is also how people reach the Fours AI assistant from Slack. Once it is connected: - **Send the app a direct message, or @mention it in a channel.** In a channel the app has to be a member — Slack delivers a mention only to an app that is part of the conversation ([Slack's `app_mention` reference](https://docs.slack.dev/reference/events/app_mention)) — so invite it first with `/invite @Suger`. There it answers only when mentioned, after reading the thread's or the channel's recent messages, with each one's author by Slack name, so it can follow the discussion. - **Who it answers.** Fours matches the email on a person's Slack profile to a Fours account in the organization this workspace is connected to. Someone without a matching account is told what is missing instead of getting an answer. - **In a channel it only reads.** Its answer is visible to everyone in the channel, so it looks things up through your connections without changing anything and never reads your private messages. Its answer is posted in the thread as usual; a separate Slack message it wants to send — to this or any other channel or person — goes out only after you allow it on the approval card. For how conversations, cards, the approval card and long replies work in Slack, see [Slack and Teams](/insulin/agents/#slack-and-teams) in the Insulin docs. ## Delete Integration Only an administrator can disconnect the org-level installation. Open the Slack card's **⋯** menu and click **Disconnect**, type `Slack` to confirm, and click **Delete**. Disconnecting removes the connection and its tokens from Fours, and Fours stops sending Slack notifications. Your notification settings — **Enable Notification** and your **Notification Scope Configs** — are kept, so when you connect Slack again they apply as before. ```d2 direction: right off: "Not connected" on: "Connected" kept: "Disconnected\nnotification settings kept" off -> on: "Connect" on -> kept: "Disconnect\ntokens removed" kept -> on: "Connect again\nsettings apply as before" ``` Your own user-level Slack connection is disconnected from its card's **⋯** menu under **User Integrations**. :::warning - Disconnecting in Fours does not uninstall the Suger app from your Slack workspace. To remove it completely, also uninstall it from [your slack workspace](https://app.slack.com/apps-manage/). ::: ## Type of Notifications Each notification scope pairs an **Action** with the **Entity** it happened to, and the **Notification Scopes** picker lists it as `ACTION.ENTITY` — for example `CREATE.OFFER`. The picker always shows the current set of scopes Fours can send to Slack. ### Offer and entitlement scopes The offer and entitlement entities and actions are listed below: | | | | ---------------- | :-------- | | `Entity` | The type of the `entity` who can do `action` is one of:
  • `OFFER`
  • `ENTITLEMENT`
| | `Action` | The action performed. Can be one of:
  • `CREATE`: the entity is created.
  • `PENDING_START`: the entity `ENTITLEMENT` is pending to start.
  • `CANCEL`: the entity is cancelled.
  • `PENDING_CANCEL`: the entity `ENTITLEMENT` is pending to be cancelled.
  • `SUSPEND`: the entity is suspended, it may be reinstated or cancelled in the future.
  • `REINSTATE`: the entity is reinstated from suspended state.
  • `UPDATE`: the entity is updated.
  • `EXPIRE`: the entity `OFFER` is expired
  • `TEST`: for testing purpose only.
| The table below summarizes what the most common actions mean for your business: ![Slack notification configuration in the Fours Console](images/integrate-slack-with-suger-1.png) | Action | Marketplace Event Description | | --- | --- | | CREATE | A new offer is generated or a buyer officially starts a subscription. | | CANCEL / SUSPEND | A contract has been terminated or paused by the buyer or provider. | | EXPIRE | A private offer has reached its end date without being accepted. | | PENDING_START | An entitlement is scheduled to begin at a future date. | | UPDATE | Metadata or resource changes have been made to an existing contract. | Here is an example of notification you will receive in your Slack channel when a new offer is created: Example new offer notification in Slack ### Partner co-sell and commission scopes If you run a partner program in Fours, the picker also offers eight co-sell scopes (`SUGERCOSELL`) and nine commission scopes (`COMMISSION`). Map them to a channel under [Notification Scope Configs](#configure-notification) to get co-sell and commission lifecycle alerts in Slack alongside the emails you already receive. Each card opens with the header below, followed by the deal name when there is one. | Scope | Card header | | --- | --- | | `CREATE.SUGERCOSELL` | **New co-sell registered** on the side that registered it; on the receiving side, **New co-sell from {partner name}** or **New co-sell shared with you** | | `REGISTER_ON_BEHALF.SUGERCOSELL` | **Co-sell registered on behalf of {partner name}**; on the partner's side, **Co-sell registered on your behalf** | | `ACCEPT.SUGERCOSELL` | **{partner name} accepted**, or **Co-sell accepted** | | `DECLINE.SUGERCOSELL` | **{partner name} declined**, or **Co-sell declined** | | `CLOSE_WON_REMINDER.SUGERCOSELL` | **Closed Won** | | `CLOSE_LOST.SUGERCOSELL` | **Closed Lost** | | `COMMISSION_TERMS_UPDATED.SUGERCOSELL` | **Commission terms updated** | | `DEAL_UPDATED.SUGERCOSELL` | **Co-sell updated** — sent only while the seller has **Partners — Deal update emails** switched on | | `PENDING.COMMISSION` | **Commission pending** | | `APPROVE.COMMISSION` | **Commission approved** | | `PAYMENT_SENT.COMMISSION` | **Payment sent** | | `PAYMENT_CONFIRMED.COMMISSION` | **Payment confirmed** | | `PAYMENT_REJECTED.COMMISSION` | **Payment rejected** | | `CLAWBACK.COMMISSION` | **Commission reversed** | | `UPDATE_PROPOSED.COMMISSION` | **Commission update needs approval** | | `UPDATE_APPROVED.COMMISSION` | **Commission update approved** | | `UPDATE_REJECTED.COMMISSION` | **Commission update rejected** | A card links to the deal or commission with **Open in Fours**, but never carries a one-click action, because anyone in the channel could click it. A copy that comes with a one-click link — the link a partner uses to approve a commission update, or to confirm a co-sell registered or closed on its behalf — is sent by email only. For what each alert contains, see [Co-Sell and Commission Alerts in Your Team's Channels](/prm/connect-slack-for-partners/#co-sell-and-commission-alerts-in-your-teams-channels). --- Source: https://doc.fours.com/integrations/snowflake/ # Snowflake Connect to Snowflake to enable real-time cloud data streaming. --- ## Overview [Snowflake](https://www.snowflake.com) is a cloud-based data warehousing platform that allows you to store and analyze large volumes of data in real-time. Connecting Fours to your Snowflake account enables you to automate tasks within Snowflake and integrate it with other applications, allowing for actions such as executing SQL queries, inserting rows, and updating rows in the database. ## Create Integration 1. Set up a Snowflake account. 2. Follow this doc to [configuring key-pair authentication](https://docs.snowflake.com/en/user-guide/key-pair-auth#configuring-key-pair-authentication). You can generate either an **encrypted** or an **unencrypted** version of the private key. :::warning - When generating an encrypted private key, the key password can **NOT** be empty. ::: 3. Click the "Connect" button on the "Integrations" page. 4. Enter Connection Information: - Account: The unique identifier for your Snowflake account, formatted as `-`. - User: The Snowflake user assigned the public key. - Warehouse (Optional): The default warehouse to be used. - Database (Optional): The default database to be used. - Schema (Optional): The default schema to be used. - Private Key: The private key file content you generated in step 2. This will start with: - `-----BEGIN PRIVATE KEY-----` for an **unencrypted** key - `-----BEGIN ENCRYPTED PRIVATE KEY-----` for an **encrypted** key. - Private Key Password(Optional): when using an **encrypted** private key, provide the password here. Example 1: Create integration using **unencrypted** private key: > Snowflake integration form with an unencrypted private key Example 2: Create integration using **encrypted** private key: > Snowflake integration form with an encrypted private key ## Edit Integration You can modify the default configurations—Warehouse, Database, and Schema—of an existing Snowflake integration. To make changes, click the `Edit` button in the "Integrations" list to open the editing dialog. > Editing dialog for the Snowflake integration Note: For security, direct credential editing is not supported. If you need to update credentials, delete the integration and recreate it. ## Delete Integration To delete the integration, simply click the 🗑️ button in the "Integrations" list. We will remove any credentials in our system. --- Source: https://doc.fours.com/integrations/stripe/ # Stripe Allow Fours to manage your Stripe seamlessly, including customers, payments. --- ## Overview Stripe is a popular online payment processing platform that allows businesses and individuals to accept payments over the internet. It provides a range of tools and services that simplify the process of setting up and managing online payments, including online payment gateway integration, merchant account services, and developer-friendly APIs. By connecting Fours to your stripe, we can build customized automation workflow in manage of customer, coupon and payment. ## How the integration works | | | | --- | --- | | **Direction** | Two-way. Fours writes to Stripe when it acts on a buyer's behalf (customers, payment methods, PaymentIntents, invoice charges) and reads from Stripe when it pulls usage for marketplace reporting. Stripe pushes state changes back over webhooks. | | **Source of truth** | Stripe owns customers, payment methods, charges and disputes. Fours owns the buyer↔customer link, the mapping to marketplace dimensions, and the usage records it reports onward. | | **Scope** | Organization-level for billing and metering. Each person can also connect their own Stripe account at the **user level**, which gives the Fours AI assistant read access to it — see [Create User Integration (OAuth)](#create-user-integration-oauth) and [Fours AI Tools](#fours-ai-tools) below. | | **Schedule** | When **Enable Auto Report Usage** is on, an hourly job at **25 minutes past the hour** pulls meter records and reports them as [usage record groups](/metering/usage-metering/). | | **Credentials** | A Stripe API key (a restricted key is recommended — see [Use Restricted Keys](#use-restricted-keys)). Fours stores it in a secret manager, not in the integration record. The publishable key is stored separately for the embedded checkout form. | ### Webhook events Fours registers a webhook endpoint in your Stripe account when the integration is created — that is why the restricted key needs **Webhook Endpoints-Write**. Deleting the integration removes the endpoint again. It subscribes to exactly these events: | Event | Why Fours listens | | --- | --- | | `charge.updated` | Charge state changed after capture | | `charge.refund.updated` | A refund progressed or failed | | `charge.dispute.created` | A dispute was opened | | `charge.dispute.closed` | A dispute was resolved | | `customer.updated` | Customer details changed in Stripe | | `payment_intent.succeeded` | A payment completed | | `payment_intent.payment_failed` | A payment attempt failed | | `payment_method.attached` | A payment method was added to a customer | | `payment_method.detached` | A payment method was removed | | `payment_method.updated` | Payment method details changed | | `payment_method.automatically_updated` | The card network pushed updated card details | | `setup_intent.requires_action` | Saving a payment method needs customer action (for example 3-D Secure) | The endpoint is pinned to the Stripe API version Fours' client uses, so a new event type appearing in Stripe does not silently change what Fours receives. ## Prerequisites Before connecting, get the following credentials from your [Stripe Dashboard](https://dashboard.stripe.com/apikeys): - **Public Key**: Your standard identifiable key. - **Secret Key or Restricted Key**: A standard Secret Key works, but Fours strongly recommends using a **Restricted Key** so you can grant least-privilege access scoped specifically to marketplace operations. See [Use Restricted Keys](#use-restricted-keys) for the required permissions. ## Create Integration In your [Fours Console Integration](https://console.suger.io/settings?tab=integrations), you will see the **Stripe** integration connection. Click the `Connect` button to create an integration with your stripe instance. This will open an dialog for you to input. > Stripe integration connection dialog in Fours Console The Public Key and Secret Key can be found in the stripe dashboard [apikeys](https://dashboard.stripe.com/apikeys). > Public Key and Secret Key location in Stripe dashboard ### Stripe Test Mode If you want to use stripe in your test environment with stripe test mode, use keys in stripe test mode dashboard [test apikeys](https://dashboard.stripe.com/test/apikeys). You may need a test suger organization to build a complete test environment. Or you can create the integration with test mode keys and then switch to live mode keys after the test is finished. ### Use Restricted Keys You can use stripe restricted keys with specific access limits and permissions for greater security. The Restricted key provided to the suger must have the following permissions. - Core resources - Balance - Read - Charges - Write - Customers - Write - Customer session - Write - Disputes - Write - Events - Read - PaymentIntents - Write - PaymentMethods - Write - Products - Write - SetupIntents - Write - Sources - Write - All Checkout resources - Write - All Billing resources - Write - All Order resources - Write - Webhook resources - Webhook Endpoints-Write > Stripe restricted key permissions configuration See more about stripe keys [stripe docs](https://docs.stripe.com/keys). Once the integration process is finished, you can proceed by clicking the `VERIFY` button. This action triggers the Fours service to test the connection to the APIs of your stripe instance. If everything is configured correctly, the integration status will be updated as `VERIFIED`. ## Manage Buyers & Customers When you use Fours' metering and billing with Stripe, each of your customers is represented by a Fours [buyer](https://doc.fours.com/billing/buyer/) that is linked to a **customer** in your Stripe account. Fours stores the Stripe customer ID on the buyer and uses it for every Stripe operation on that buyer's behalf — collecting payment methods, charging via PaymentIntents, applying charges to invoices, and matching incoming Stripe webhooks. ### How the link is established The link between a Fours buyer and a Stripe customer is established **when the buyer is created**, based on the optional **Stripe Customer ID** field: - **Stripe Customer ID provided** — Fours connects the buyer to that existing Stripe customer. It verifies the customer exists, tags it with a `sugerBuyerId` metadata entry pointing back to the Fours buyer, and imports the customer's saved payment methods into the buyer's wallet. No new Stripe customer is created. - **Stripe Customer ID left blank** — Fours automatically creates a new Stripe customer, populated from the buyer's name, description, and company address, and tagged with the same `sugerBuyerId` metadata. > **Duplicate protection:** If another buyer in your organization is already linked to the Stripe Customer ID you provide, buyer creation is rejected. This prevents two Fours buyers from pointing at the same Stripe customer. ### The link is set only at creation The Stripe Customer ID **cannot be changed after the buyer is created**. Editing a buyer does not re-connect it to a different Stripe customer or create a new one — only the create step performs the connect-or-create logic. To link a buyer to a different Stripe customer, create a new buyer. ### Payment methods and wallets Payment methods are collected securely through the Stripe SDK; sensitive card details are never stored in Fours. A buyer's wallet supports the following types, which map to Stripe payment methods: | Wallet type | Stripe payment method | Typical currency | |---|---|---| | Card | Card | All | | ACH Debit | US bank account | USD | | SEPA Debit | SEPA debit | EUR | | BACS Debit | BACS debit | GBP | | Credit | — (managed by Fours) | Buyer's currency | Credit is a Fours-managed balance rather than a Stripe object; it functions like store credit and is applied automatically during invoice payment. A default payment method can be set for a buyer to prioritize it when paying invoices. ## Create User Integration (MCP) Stripe also runs its own MCP server, `https://mcp.stripe.com`. Connecting it as a custom MCP server gives your Fours AI sessions the tools Stripe's server offers; it is separate from the Stripe tools in [Fours AI Tools](#fours-ai-tools). The connection acts **on behalf of you**, a member of the Stripe account, not the organization: you authorize it on Stripe's consent page, where you choose which live accounts or sandboxes it can reach. See [Stripe MCP documentation](https://docs.stripe.com/mcp) for details. ### Prerequisites An administrator of your Stripe account controls MCP access for the whole team in the Stripe Dashboard's [MCP and CLI access](https://dashboard.stripe.com/settings/mcp-and-cli-access) settings, separately for live mode and sandboxes ([Stripe MCP documentation](https://docs.stripe.com/mcp)). Make sure it is enabled before you connect. > MCP access toggle in Stripe Team and security settings ### Connect 1. In **Settings → Integrations**, scroll to **Custom MCP Servers** and click **Add MCP server**. 2. In **Connect a custom MCP server**, find **Stripe** under **Popular MCP Servers** and click **+** on its card. 3. Stripe's consent page opens in a new tab. Sign in, choose what to grant, and approve. 4. Back in Fours, the dialog closes with *MCP server connected successfully*, and Stripe appears under **Custom MCP Servers**. ## Create User Integration (OAuth) Connect your own Stripe account to Fours through [Stripe Connect](https://docs.stripe.com/connect) OAuth. This gives the Fours AI assistant read access to that account — see [Fours AI Tools](#fours-ai-tools). 1. In **Settings → Integrations**, under **User Integrations**, find the **Stripe** card and click **Connect**, then click **Start connection** in the **Connect Stripe** dialog. 2. Stripe's authorization page opens in a new window. Sign in if Stripe asks you to, and authorize the connection. 3. When the dialog shows **Stripe is connected.**, click **Close**. Fours requests Stripe Connect's `read_write` scope, because Stripe lets only extensions request `read_only` ([Stripe's OAuth reference](https://docs.stripe.com/connect/oauth-reference)). Fours AI still uses the connection only through the tools in [Fours AI Tools](#fours-ai-tools), none of which creates a payment, an invoice or a committed tax transaction. The two ways to connect Stripe as yourself, side by side: ```d2 shape: sequence_diagram you: "You" fours: "Fours" stripe: "Stripe" oauth: "Stripe card under User Integrations (Stripe Connect OAuth)" { you -> fours: "Connect, then Start connection" fours -> stripe: "Open the authorization page (read_write)" you -> stripe: "Sign in and authorize" stripe -> fours: "Access to your Stripe account" { style.stroke-dash: 4 } fours -> you: "Stripe is connected. Fours AI gets the Stripe tools" { style.stroke-dash: 4 } } mcp: "Stripe under Custom MCP Servers (Stripe's MCP server)" { you -> fours: "Add MCP server, then + on the Stripe card" fours -> stripe: "Open Stripe's consent page" you -> stripe: "Choose what to grant, approve" stripe -> fours: "Access to Stripe's MCP server" { style.stroke-dash: 4 } fours -> you: "MCP server connected. Fours AI gets Stripe's MCP tools" { style.stroke-dash: 4 } } ``` > **Note:** If your Stripe account is already **controlled by another platform**, this connection will fail. Since June 2021, Stripe does not allow a second platform using `read_write` OAuth scope to connect to a controlled account. You must disconnect from the controlling platform first. See [Stripe's OAuth reference](https://docs.stripe.com/connect/oauth-reference) for details. ## Fours AI Tools Both Stripe connections give Fours AI the same Stripe tools: the org-level integration through its API key, and a user-level connection through your own Stripe account. They read your account and preview tax; none of them creates a payment, an invoice or a committed tax transaction. | Tool | What it does | |------|--------------| | `stripe_get_balance` | Get the current balance — available and pending funds per currency | | `stripe_list_balance_transactions` | List money movements — charges, refunds, payouts and fees — over a time window | | `stripe_list_charges` | List individual payments | | `stripe_list_payouts` | List payouts to your bank account | | `stripe_list_subscriptions` | List subscriptions — active ones by default, or every status | | `stripe_list_invoices` | List invoices | | `stripe_get_tax_settings` | Get your Stripe Tax settings, including status, defaults and head-office address | | `stripe_list_tax_codes`, `stripe_get_tax_code` | List product tax codes, or get one | | `stripe_list_tax_rates`, `stripe_get_tax_rate` | List tax rates, or get one — for manual-tax setups | | `stripe_create_tax_calculation` | Preview the tax for a customer address and line items | Which connection a run uses depends on the agent, not on which connections exist: the Fours AI assistant and agents you own use your user-level Stripe connection, and org-level agents use the organization's integration. See [User-Level vs Org-Level Agents](/insulin/agents/#user-level-vs-org-level-agents). Stripe's own MCP server is a separate connection with its own tools — see [Create User Integration (MCP)](#create-user-integration-mcp). ## Edit Integration Open the Stripe integration from **Settings → Integrations** and click **Edit**. The dialog covers four settings: - **Enable Auto Report Usage**: When enabled, an hourly cron job fetches usage metering records from Stripe and reports them to Fours as [usage record groups](/metering/usage-metering/). Leave it off if you meter somewhere other than Stripe. - **Billing Mode**: How usage is measured for that report. **`quantity`** is the mode Fours can run today. - **Billing Source**: Where in Stripe the usage is read from. For `quantity`, the source is **`usage_record`**. - **Enable Entitlement End Soon Notification**: When enabled, specify the number of days (10-60) before an entitlement ends to trigger notifications. Fours will send an initial notification when Stripe Marketplace entitlements approach ending, followed by reminders every 5 days. To configure recipients, follow the [email notification configuration guide](/settings/email-notification/#configuration) and add the scope `END_SOON.ENTITLEMENT`. :::caution[Auto Report Usage needs a supported Billing Mode and Source] `quantity` → `usage_record` is the only combination the hourly sync can actually execute. Other combinations that existed previously — `amount`, and `meter_event` as a source — are no longer offered, because the sync cannot run them. If **Enable Auto Report Usage** is switched on while Billing Mode and Billing Source are not both set to a supported combination, the integration looks armed but reports nothing: the dialog shows an alert saying so. That is easy to reach by accident, because neither field is set when the integration is first created — turning the toggle on and closing the dialog is enough. **Set the pair as well as the toggle.** If your integration still holds a value that is no longer supported, the dropdown shows it, greyed out, alongside a note saying it is unavailable. It stays visible so you can see what is stored rather than facing a blank control; pick `quantity` / `usage_record` to replace it. ::: The org-level Stripe card also reports when its stored API key has stopped working — for example after the key is rolled or revoked in Stripe. See [Connection health](/integrations/#connection-health). ## Delete Integration The stripe integration can be deleted like all other integrations. Once the deletion is triggered, no time window or methods to recover. --- Source: https://doc.fours.com/integrations/together/ # Together AI Connect your Together AI API key to run Fours' AI features on the models Together serves. --- ## Overview Together AI is an AI model provider (category: AI). By connecting your own Together AI API key (bring-your-own-key), the models Together offers become selectable in Fours' model picker — for Insulin agents, chat, inference, and knowledge-base embeddings. API usage is billed directly by Together to your account; Fours does not charge for these models. ### Org-Level vs User-Level - **Org-Level**: the key is shared across your organization. Its models are available to organization-level agents and to members of the org. Connecting requires an organization admin. - **User-Level**: the key is personal to your workspace. Its models are available to your own user-level agents and personal Insulin. --- ## Create Integration 1. Navigate to the [Fours Console Integrations](https://console.suger.io/settings?tab=integrations) page. 2. Find the **Together AI** integration and click **Connect**. 3. Choose the level — **Organization** (shared) or **User** (personal). 4. Paste your **Together AI API Key** and click **Save credentials**. Fours verifies the key with Together before storing it, so an invalid key is rejected at connect time rather than surfacing later as a failed model run. > Generate an API key in your Together AI account at [together.ai](https://www.together.ai/) (**API Keys**). :::info After connecting, open any model picker — an agent's **Default Model**, or **Insulin model settings** — and Together AI's models appear, with verified models grouped first and each entry attributed to Together AI. ::: ## Edit Integration Editing the API key is not supported. To change the key, delete the integration and create a new one. ## Delete Integration You can delete the Together AI integration at any time. This permanently removes the stored credential. Any agent pinned to a Together AI model then shows that model as **unavailable** with a reconnect prompt until you reconnect Together AI or pick another model — Fours never silently substitutes a different model. :::info Together AI also serves knowledge-base embeddings on your own key: **Together · multilingual-e5-large-instruct**, its only embedding model, appears in the embedding-model chooser once this integration is connected at the knowledge base's level — an organization connection for an organization knowledge base, your personal connection for a private one. Organization knowledge bases can also use the Fours-hosted models, which need no key — see [Knowledge Bases](../../insulin/knowledge-base/). ::: --- Source: https://doc.fours.com/integrations/workday/ # Workday Connect Workday so Fours AI can read your worker, organization, and time-off data. --- ## Overview [Workday](https://www.workday.com) is an enterprise platform for human capital management and finance. Connecting it lets the Fours AI agent read your HR data — workers, organizations, job requisitions, compensation, and time off — and submit time-off requests, from a Fours workflow or chat. ### Org-Level vs User-Level > **Org-Level**: Supported, using an OAuth client-credentials exchange against your own Workday tenant. > > **User-Level**: Not currently available. The API client is registered inside your own tenant rather than centrally, so there is no single Fours app your users could sign in to. ### How the connection works The API client is registered in **your** Workday tenant. Fours exchanges its client ID and secret for an access token against your tenant's own token URL, and refreshes that token when it expires — Fours registers nothing on your behalf and holds no Workday client of its own. ```d2 shape: sequence_diagram admin: "Your Workday admin" workday: "Your Workday tenant" suger: "Fours" agent: "Fours AI agent" admin -> workday: "Register an API client and grant security domains" admin -> suger: "Client ID + Secret, token domain, tenant" agent -> suger: "Run a Workday tool" suger -> workday: "Exchange the client pair at your tenant's token URL" workday -> suger: "Access token + expiry — Fours refreshes on expiry" { style.stroke-dash: 4 } suger -> workday: "REST or WQL read" workday -> agent: "Workers, organizations, requisitions, time off" { style.stroke-dash: 4 } ``` ## Create Integration (Org-Level) ### Prerequisites - A Workday tenant with REST API access enabled. - Permission to run the **Register API Client** task (typically a security administrator). - Your tenant's **host** and **tenant name**. These are not discoverable by Fours — expect to get them from whoever administers Workday. The host looks like `wd3-impl-services1.workday.com`; the tenant name is the short identifier in your Workday URLs. - The Fours **Admin** role — connecting, disconnecting, and running an integration's actions are all admin-only in Fours. ### Authenticate by client credentials 1. In Workday, run the **Register API Client** task and register a client for integrations. 2. Grant it the security domains covering the data you want Fours to reach — Worker Data, Organization Information, Time Off, and so on. A missing domain makes the matching tool fail. 3. Copy the **Client ID** and **Client Secret**. 4. In the Fours console, open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) and click **Connect** on **Workday**. 5. Enter: - **Token Domain** — your Workday host, for example `wd3-impl-services1.workday.com`. - **Tenant** — your tenant name. - **Client ID** and **Client Secret** — from step 3. 6. Save. :::info The API client belongs to *your* tenant — Fours registers nothing on your behalf and holds no Workday client of its own. Revoking the client in Workday immediately breaks the connection. ::: ## Fours AI Tools When Workday is connected, the Fours AI agent can read HR data through Fours' built-in tools (15 actions). > **Org-level**: Every tool runs under the registered API client, so its security-domain grants set the ceiling on what the agent can reach. | Capability | What the agent can do | |------------|-----------------------| | **Workers** | Read and list workers, and read one worker's compensation (e.g. `get-worker`, `list-workers`, `get-worker-compensation`) | | **Organizations** | Read and list organizations, including supervisory organizations (e.g. `get-organization`, `list-supervisory-organizations`) | | **Job requisitions** | Read and list job requisitions (`get-job-requisition`, `list-job-requisitions`) | | **Time off** | Read a time-off detail, list a worker's time off and absence balances, and submit a time-off request (e.g. `list-worker-time-off`, `submit-time-off-request`) | | **Custom queries** | Run a Workday Query Language (WQL) query, and read a custom object definition (`execute-wql-query`, `get-custom-object-definition`) | :::info Aside from `submit-time-off-request`, these tools are read-only. Workday is the newest of Fours' HR connectors and its tool set is deliberately narrow — `execute-wql-query` is the escape hatch for anything the typed tools don't cover. ::: :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration Editing is not supported. To rotate the client secret or point Fours at a different tenant, delete the integration and create it again. ## Delete Integration Click the 🗑️ button next to **Workday** in the **Integrations** list. The stored client pair is destroyed with the integration record. Revoke the API client in Workday too if you want to cut access from that side. --- Source: https://doc.fours.com/integrations/zuora/ # Zuora Connect to Zuora to manage billing, subscriptions, and revenue data. --- ## Overview [Zuora](https://www.zuora.com) is a subscription management and recurring billing platform that helps businesses automate the entire quote-to-revenue lifecycle. It provides comprehensive solutions for subscription billing, revenue recognition, and customer lifecycle management. Connecting Fours to your Zuora tenant lets the Fours AI agent read your billing data — accounts, subscriptions, invoices, and payments — from a Fours workflow or chat. ### Org-Level vs User-Level > **Org-Level**: Supported, using Zuora's OAuth 2.0 client-credentials grant. > > **User-Level**: Not applicable. Zuora's REST API offers client credentials and nothing else — there is no three-legged flow an individual Fours user could consent to — so a per-user connection is impossible rather than merely absent. Every Fours user in your organization shares the org connection. ### How the connection works The OAuth client is created in **your** Zuora tenant. Fours exchanges its client ID and secret for a bearer token and refreshes it for you — nothing in Fours mints or caches Zuora tokens itself. The subdomain you supply builds the host used for *both* the token exchange and every API call, which is why it must be the subdomain alone. ```d2 shape: sequence_diagram admin: "Your Fours admin" zuora: "Your Zuora tenant" suger: "Fours" agent: "Fours AI agent" admin -> zuora: "Create an OAuth client under a role-scoped Zuora user" admin -> suger: "Client ID + Secret, subdomain (e.g. rest)" suger -> suger: "Build https://{subdomain}.zuora.com\nfor the token exchange AND every API call" agent -> suger: "Run a Zuora tool" suger -> zuora: "client_credentials grant" zuora -> suger: "Bearer token — Fours refreshes it" { style.stroke-dash: 4 } suger -> zuora: "Read accounts, subscriptions, invoices, payments" zuora -> agent: "Data — or a hard error; a failed call never reads as an empty result" { style.stroke-dash: 4 } ``` ## Create Integration (Org-Level) ### Prerequisites - A Zuora account. - Permission to create an OAuth client in your Zuora tenant. - The Fours **Admin** role — connecting, disconnecting, and running an integration's actions are all admin-only in Fours. ### Authenticate by client credentials 1. Create an OAuth client in your Zuora tenant, under a user with the permissions you want Fours to operate with. Zuora scopes the client to that user's role. Capture the **Client ID** and **Client Secret** — see the [Zuora OAuth documentation](https://developer.zuora.com/api-references/api/overview/#section/Authentication/OAuth-v2.0). 2. In the Fours console, open [Settings → Integrations](https://console.suger.io/settings?tab=integrations) and click **Connect** on **Zuora**. 3. Enter: - **Subdomain** — the label between `https://` and `.zuora.com`, for example `rest`. Common values: | Environment | Subdomain | | --- | --- | | US Production | `rest` | | US Cloud 1 Production (NA) | `rest.na` | | US API Sandbox | `rest.apisandbox` | | US Performance Test (PT1) | `rest.pt1` | | EU Production | `rest.eu` | | EU API Sandbox | `rest.sandbox.eu` | - **Client ID** and **Client Secret** — from step 1. 4. Save. :::warning Enter the **subdomain only** — not a full URL. Fours builds both the token endpoint and the API base from it as `https://{subdomain}.zuora.com`, so pasting `https://rest.zuora.com` would produce an unusable host. The connect form rejects values containing a scheme or a trailing `.zuora.com`. ::: ### Check the connection Fours re-checks the stored credential against Zuora rather than trusting a cached token, so a client secret revoked in Zuora is noticed even while the token it issued has not yet expired. You see the result on the Zuora card in the **Integrations** list. When the stored credential stops working the card says so directly: > Connected, but this integration's stored credential can no longer be used — agents and workflows cannot reach it. Disconnect and connect it again to restore access. This is the same check every org integration gets — see [Connection health](/integrations/#connection-health) for what it does and how to read a card that does not show it. :::warning **Connected Zuora before this update? Reconnect it to get the AI tools back.** Zuora now connects a different way. An older connection is **not** dead: Fours still reads your Zuora data through it, carried by a temporary compatibility fallback, so billing and revenue data keep flowing. What an older connection does **not** get is the Fours AI agent's Zuora tools — those are unavailable until you reconnect. Delete the integration and create it again with the steps above. Reconnecting is the only fix; nothing converts an older connection for you, and the compatibility fallback is temporary — plan the reconnect rather than relying on it. ::: ## Fours AI Tools When Zuora is connected, the Fours AI agent can read your billing data through Fours' built-in tools (6 actions). > **Org-level**: All tools run under the org OAuth client, so its Zuora role sets the ceiling on what the agent can read. | Capability | What the agent can do | |------------|-----------------------| | **Accounts** | Read one account by ID or account number, and list or search accounts using a Zuora Object Query filter (`get-account`, `list-accounts`) | | **Subscriptions** | Read a subscription by ID or number, and list the subscriptions on an account (`get-subscription`, `list-subscriptions`) | | **Invoices** | List the invoices on an account (`list-invoices`) | | **Payments** | List the payments on an account (`list-payments`) | :::info This tool set is read-only — no Zuora record can be created or modified through it. A call Zuora rejects surfaces as an error, never as an empty result, so the agent cannot mistake a failure for "nothing found". ::: :::tip Open the integration from **Settings → Integrations** to see the exact tool list for your connection on its **Actions** tab, and to try a call on the **Playground** tab. The Playground pre-fills only the inputs an action *requires* — add optional ones yourself when you need them. ::: ## Edit Integration Editing is not supported. For security, if you need to rotate credentials or switch tenants, delete the integration and recreate it. ## Delete Integration To delete an integration, click the 🗑️ button next to its entry in the **Integrations** list. Fours discards the stored credentials with the integration record, and any workflow or agent depending on Zuora tools stops working immediately. Revoke the OAuth client in Zuora too if you want to cut access from that side. --- Source: https://doc.fours.com/oracle-marketplace/integration/ # Integration Grant Fours the necessary access to manage your Oracle Cloud Marketplace on your behalf, no more no less. --- ## Overview To sell on Oracle Cloud Marketplace, you first need to be an approved Oracle Cloud Marketplace publisher. Publishing requires an Oracle Cloud account and an approved publisher profile in the [Oracle Cloud Marketplace Partner Portal](https://cloudmarketplace.oracle.com/marketplace/en_US/partnerLandingPage). More details can be found in the [Oracle Cloud Marketplace publisher documentation](https://docs.oracle.com/en-us/iaas/Content/Marketplace/overview.htm). Once you are a publisher with listings in your Oracle Cloud (OCI) tenancy, you can integrate with Fours to sync your listings, manage private offers, and track revenue. Fours authenticates to OCI with an **API signing key** of an IAM user in your tenancy — the same key-based authentication used by the OCI CLI and SDKs. :::note **Org-Level only.** Oracle Cloud Marketplace connects with an organization-wide OCI API signing key and does not support user-level integrations. ::: ```d2 direction: down user: "1 · IAM service user\noracle-marketplace@suger.io\n(dedicated, least-privilege)" group: "2 · Group MarketplaceSugerIO\n+ tenancy-scoped IAM policy:\nmarketplace-offers ·\nmarketplace-publisher-family ·\nusage-record create" key: "3 · API signing key\ndownload the private .pem\n(no passphrase) + fingerprint" config: "Config file preview\ntenancy OCID · user OCID ·\nfingerprint" form: "4 · Fours → Integrations →\nOracle Cloud Marketplace → Connect\nAutofill from config, paste the .pem" verify: "Fours verifies by reading your\nMarketplace Publisher listings\n(a new key can take ~2 min to replicate)" vault: "Private key stored in Fours'\nsecret store — never shown again" user -> group user -> key key -> config config -> form: "paste + Autofill from config" key -> form: "paste the private key" group -> verify: "grants the read" { style.stroke-dash: 4 } form -> verify -> vault ``` ## Integration Prerequisite ### 1. Create a dedicated IAM service user Create a dedicated, least-privilege IAM user for Fours named `oracle-marketplace@suger.io`. Do not use a personal or administrator account. See [Managing Users](https://docs.oracle.com/en-us/iaas/Content/Identity/users/about-managing-users.htm) in the OCI documentation. ### 2. Grant Marketplace Publisher permissions Add the `oracle-marketplace@suger.io` user to a group named `MarketplaceSugerIO` and create an IAM policy that grants the group access to Marketplace Publisher resources, private offers, and usage records: ``` Allow group MarketplaceSugerIO to manage marketplace-offers in tenancy Allow group MarketplaceSugerIO to manage marketplace-publisher-family in tenancy Allow group MarketplaceSugerIO to {MARKETPLACE_SELF_SUBSCRIPTION_USAGE_RECORD_CREATE} in tenancy ``` :::note The usage-record permission is required for [Oracle usage metering](/oracle-marketplace/usage-metering/). Without it, Fours' hourly usage submissions are rejected by OCI with an authorization error. Grant it even if you do not report usage today, so metering works without a second IAM change later. ::: :::note Private offers exist at the **tenancy** level, so these statements must be scoped to the tenancy, not to a compartment. See Oracle's [Required IAM Policies for private offers](https://docs.oracle.com/en-us/iaas/Content/Marketplace/privateoffers-required-iam-policies.htm) and [Marketplace Publisher IAM policy reference](https://docs.oracle.com/en-us/iaas/Content/Marketplace/publisher-iam-policy.htm). ::: ### 3. Add an API signing key to the service user Follow the [official guideline](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm) to add an API key: 1. In the OCI Console, go to **Profile → User settings → API keys → Add API key** (for the service user). 2. Generate a key pair and **download the private key** (`.pem` file). Keep it safe — OCI does not show it again. 3. Note the key **fingerprint** and the **configuration file preview** shown after the key is added. The preview contains the user OCID, tenancy OCID, region, and fingerprint — you can paste it into Fours to fill in the tenancy OCID, user OCID and fingerprint (Fours ignores the region line). :::note **Encrypted (passphrase-protected) private keys are not supported yet.** Generate the key without a passphrase. ::: ## Connect in Fours Console 1. Go to the **Integrations** page in the Fours console and click `Connect` on the **Oracle Cloud Marketplace** integration. 2. (Optional) Paste the **configuration file preview** from the OCI Console into the *Quick fill from OCI config* box and click `Autofill from config`. Both the `[DEFAULT]` config-file format and a JSON object are accepted. 3. Fill in the remaining fields: | Field | Description | |---|---| | **Tenancy OCID** | The OCID of your Oracle Cloud tenancy (Console → Profile → Tenancy). | | **User OCID** | The OCID of the dedicated IAM service user created above. | | **API Key Fingerprint** | The fingerprint of the public API signing key uploaded to the user. | | **API Signing Private Key (PEM)** | The downloaded private key. Paste it or load it from the `.pem` file. | | **Compartment OCID** (optional) | Scopes catalog reads to a compartment. Leave empty to use the tenancy root — recommended, especially when transacting private offers. | There is no Region field: Fours makes its Marketplace Publisher calls in `us-ashburn-1`, and ignores a region in a pasted configuration. 4. Click `Connect` to complete the integration. Fours verifies the credentials by reading your Marketplace Publisher listings. :::note A freshly created user or API key can take ~2 minutes to replicate inside OCI before verification succeeds. If verification fails right after creating the key, wait a moment and retry. ::: The private key is stored in Fours' secret store and is never returned by the API or shown in the console again. ## Edit Integration In the Fours console, editing the Oracle Cloud Marketplace integration changes only its **Display Name** — the credentials are write-only. To change the tenancy OCID, user OCID, fingerprint or compartment, or to rotate the API signing key, delete the integration and connect it again with the new values, or update it through the Fours API, where supplying a new private key replaces the stored one and leaving it empty keeps it. ## Delete Integration The Oracle Cloud Marketplace integration can be deleted like all other integrations. Once the deletion is triggered, all integration info including the **API signing private key** is deleted immediately & permanently from Fours. No time window or methods to recover. :::warning Deleting the integration may affect active marketplace offers and entitlements synced from Oracle. ::: --- Source: https://doc.fours.com/oracle-marketplace/list-product/ # List Product Sync your Oracle Cloud Marketplace listings into Fours. --- ## Where Listings Are Created Listings themselves are created and managed in the [Oracle Cloud Marketplace Partner Portal](https://cloudmarketplace.oracle.com/marketplace/en_US/partnerLandingPage) — Fours does not create or publish Oracle listings. Fours **imports** your existing listings so you can transact private offers against them. ## Sync Listings into Fours Once the [integration](/oracle-marketplace/integration/) is connected, Fours keeps your Oracle data fresh automatically: - An initial sync runs when the integration is connected. - After that, Fours re-syncs every connected Oracle integration **hourly**, pulling the latest listings and private-offer statuses. - You can also trigger a sync on demand from the **Integrations** page in the Fours console (the `Sync` action on the Oracle Cloud Marketplace integration) — for example, right after publishing a new listing. The sync imports your Marketplace Publisher listings as Fours **products**, along with any private offers already sent from your tenancy. ## What Gets Synced - Your **published SaaS listings** (Oracle listing package type `SAAS`) are synced. Other Oracle Marketplace listing types (container images, machine images, stacks, and Helm charts) are out of scope and skipped. - Each listing becomes a product in Fours, keyed by its Oracle listing ID, so re-running the sync updates existing products instead of duplicating them. - Products you have edited or deleted in Fours are left untouched by later syncs. - The raw Oracle listing data is preserved on the Fours product for auditing. ### Listing Status Mapping | Oracle listing lifecycle state | Fours product status | |---|---| | `ACTIVE` | `PUBLIC` | | `INACTIVE` | `UNLISTED` | | `CREATING` | `PENDING` | | `UPDATING` | `PENDING_UPDATE` | | `DELETING` / `DELETED` | `DELETED` | | `FAILED` | `CREATE_FAILED` | After the sync completes, your Oracle listings appear on the **Products** page and are ready to be used in [private offers](/oracle-marketplace/private-offers/). --- Source: https://doc.fours.com/oracle-marketplace/private-offers/ # Private Offers Create a private offer to sell your SaaS listing to a specific Oracle Cloud customer at negotiated terms. --- ## Prerequisites - The [Oracle Cloud Marketplace integration](/oracle-marketplace/integration/) is connected. - Your SaaS listing has been [synced into Fours](/oracle-marketplace/list-product/) as a product. - You know the buyer's **tenancy OCID** (`ocid1.tenancy.oc1..…`) — the offer is sent to this tenancy. - Your contract document (EULA) as a **PDF file, up to 1 MB**. ## Pricing Model Oracle Cloud Marketplace private offers created through Fours are priced as a **one-time contract value in USD**: - The buyer commits to a single **total contract value** in USD (rounded to whole dollars) for the full contract duration. - Billing cycle is **one-time** — no installments. The offer price itself is not usage/metered; [usage metering](/oracle-marketplace/usage-metering/) is a separate, entitlement-level capability that bills **in addition to** the contract value, not instead of it. - Contract length: billing ends after a duration you set in whole **days, months or years** (1 year by default), or on a specific end date. Oracle's maximum total contract length is **375 days**, so anything longer — a 2-year duration, for example — is rejected at send time. :::warning **Oracle's contract limits are enforced by Oracle, not by Fours.** Beyond requiring a positive value, a positive whole-number duration and dates in the right order (see the form fields below), the console does not check your offer against Oracle's own limits — it sends what you enter, and Oracle rejects anything outside its range at send time, leaving the offer in `Create Failed`. Oracle publishes a **minimum contract value of 10,000 USD** (or the equivalent in another supported currency) and a **maximum total contract length of 375 days** — one year plus 10 days. So a duration longer than 375 days, and any value under 10,000 USD, fall outside those limits. See Oracle's [Managing Private Offers](https://docs.oracle.com/en-us/iaas/Content/Marketplace/manage-private-offers.htm). ::: ## Create a Private Offer 1. On the **Offers** page in the Fours console, click `Create Private Offer` and select your Oracle product. 2. Fill in the offer details: | Field | Description | |---|---| | **Offer name** | Required. A descriptive name for this offer (max 128 characters). | | **Buyer company name** | Optional. | | **Buyer tenancy OCID** | Required. The OCID of the buyer's Oracle Cloud tenancy. | | **Buyer primary contact** | First/last name and email. The email is required. | | **Offer description** | Optional (max 512 characters). | | **Billing start** | **On acceptance** (default) — billing starts when the buyer accepts. **Specify date** — pick the start date. | | **Billing end** | **End after duration** — a whole number of **Days**, **Months** or **Years** (default 1 year), measured from the start. **End on specific date** — must be after the start date. Oracle's maximum is 375 days. | | **Offer expiration date** | The date by which the buyer must accept. If you leave it empty, Fours uses 30 days from creation, or the day before the billing start date if that is sooner. With a specified start date, it must be before that date — Oracle rejects the offer otherwise. | | **Contract document (EULA)** | Required. A PDF file up to 1 MB. The form takes exactly one document; to attach additional contract documents, create the offer through the [Fours API](/oracle-marketplace/create-private-offer-api/). | | **Total contract value** | Required. The one-time amount in USD. Fours requires it to be greater than 0; Oracle additionally requires a minimum of 10,000 USD. | | **Seller primary contact** | First/last name and email. The email is required. | Fields marked with an asterisk (*) are required. **Create offer** stays greyed out while a required field is empty or a value isn't valid; hover over it, or press Tab until it has focus, to see what's left — its tooltip, headed *Please complete:*, lists each step that still needs work and the fields in it. The form also checks the offer terms as you fill them in: a value that isn't valid is outlined in red with the reason beneath it — *Must be before the billing start date: Oracle rejects the offer otherwise* under **Offer Expiration Date**, *Must be after the billing start date* under **Billing End**, or *Must be a whole number greater than 0* for a contract duration. Oracle accepts contract lengths only in days, so Fours converts months and years into the exact number of days from the start before sending — 1 year becomes 365 or 366 days. The offer's detail page shows the stored duration, for example `365 days (P365D)`. 3. Submit the offer. Fours creates the offer in Oracle Cloud, attaches the contract document, and sends it to the buyer's tenancy. Sending is asynchronous on Oracle's side: the offer stays in `Pending Create` while Fours waits (up to ~5 minutes) for Oracle to confirm the send. Once confirmed, the offer moves to `Pending Acceptance`. If Oracle rejects the send, the offer moves to `Create Failed`, and its **Create Offer Failed** alert shows Oracle's reason — such as `DURATION_IS_INVALID` or `TIME_ACCEPT_BY_IS_INVALID` — so you can fix the offer and resubmit it (see [Modify a Private Offer](#modify-a-private-offer)). ## Offer lifecycle An offer moves from creation to a buyer entitlement like this: ```d2 direction: down a: "Create offer in Fours" b: "Pending Create\nFours waits ~5 min for Oracle to confirm the send" c: "Pending Acceptance\nsent to the buyer's tenancy" d: Accepted e: "Active\ncontract in effect" f: "Entitlement created automatically in Fours\nActive at once when billing starts on acceptance;\nwith a start date, Pending Start until then" g: Expired h: "Create Failed" a -> b b -> c c -> d: "Buyer accepts in the Oracle Cloud Console" d -> e d -> f: "on acceptance" c -> g: "Offer expires unaccepted" b -> h: "Send fails" ``` ## Offer Status Oracle offer statuses map to Fours offer statuses as follows: | Oracle offer status | Fours offer status | Meaning | |---|---|---| | `DRAFT` | `Draft` | Created in Oracle but not yet sent. | | `PENDING_MARKETPLACE` | `Pending Marketplace Approval` | Waiting on Oracle Marketplace review. | | `PENDING_BUYER` | `Pending Acceptance` | Sent; waiting for the buyer to accept. | | `ACCEPTED` | `Accepted` | The buyer accepted the offer. | | `ACTIVE` | `Active` | The contract is in effect. | | `ENDED` / `EXPIRED` | `Expired` | The contract ended, or the offer expired unaccepted. | | `FAILED_SEND` / `FAILED_ACCEPT` | `Create Failed` | Oracle rejected the send or the acceptance failed. | Buyers are matched by their Oracle **tenancy**, so repeat deals with the same buyer are recognized. ## Buyer Acceptance The buyer reviews and accepts the private offer in their **Oracle Cloud Console** — there is no in-Fours acceptance step. The buyer's user needs tenancy-scoped IAM permission to accept offers, e.g.: ``` Allow group PrivateOfferBuyer to manage marketplace-offers in tenancy ``` See Oracle's [Required IAM Policies for private offers](https://docs.oracle.com/en-us/iaas/Content/Marketplace/privateoffers-required-iam-policies.htm). Acceptance is reflected back into Fours when the offer status advances — the hourly sync picks it up automatically, or trigger a sync from the **Integrations** page to pull the latest statuses immediately. ## After Acceptance: Entitlement Fours creates a private **entitlement** as soon as the offer reaches **Accepted** — it does not wait for `Active`. The entitlement's own status then follows the offer's billing start: | Offer status | Billing start date | Entitlement status | |---|---|---| | `Accepted` or `Active` | None — billing starts on acceptance | `Active` | | `Accepted` or `Active` | Still in the future | `Pending Start` | | `Accepted` or `Active` | Reached | `Active` | This means a deal closed today with a start date next quarter shows up in Fours right away as a `Pending Start` entitlement, and flips to `Active` on the start date without anyone touching it. An offer that starts billing on acceptance — the default — gets an `Active` entitlement straight away. - Start time comes from the offer's billing start date, when it has one; end time from the offer end date (or start date + contract duration). - The entitlement carries the offer's currency and total contract value as its commit amount. - When the offer ends in Oracle, the entitlement is closed automatically on the next sync. [Usage metering](/oracle-marketplace/usage-metering/) requires an active entitlement, so a `Pending Start` entitlement is not yet a metering target. ## Cancel a Private Offer You can cancel (withdraw) a private offer **before the buyer accepts it**: 1. Select the offer on the **Offers** page. 2. Click `Cancel` and confirm in the popup dialog. Fours withdraws the offer in Oracle, and the buyer can no longer accept it. :::note Oracle does not allow withdrawing an offer that the buyer has **already accepted**. Cancellation only works while the offer is pending acceptance. ::: ## Modify a Private Offer Oracle private offers cannot be amended after they are sent. To change the terms of an unaccepted offer, cancel it and create a new offer. If an offer failed to send (`Create Failed`) or is stuck in `Draft`, simply re-submit it from Fours: the stale Oracle draft is cleaned up and a fresh offer is created and sent — no duplicates are produced. --- Source: https://doc.fours.com/oracle-marketplace/faq/ # FAQ Frequently asked questions about selling on Oracle Cloud Marketplace with Fours. ## Which listing types are supported? **SaaS listings** (package type `SAAS`) only. Other Oracle Marketplace listing types — container images, machine images, stacks, and Helm charts — are not synced and cannot be used in offers created through Fours. ## Which pricing models are supported for private offers? A **one-time total contract value in USD** for a fixed contract length. In the console you set that length as a whole number of **days, months or years**, or as a specific end date, and Fours requires the value to be greater than 0 — Oracle's own minimum is far higher, see below. Installment plans are not supported. Usage/metered pricing is not part of the offer itself — usage metering is a separate, entitlement-level capability that bills on top of the contract value (see [Usage Metering](/oracle-marketplace/usage-metering/)). Fours sends whatever you enter and imposes no minimum or maximum of its own. Oracle publishes a **minimum contract value of 10,000 USD** (or the equivalent in another supported currency) and a **maximum total contract length of 375 days**, so a longer contract — a 2-year duration, for example — falls outside Oracle's range and is rejected at send time. See Oracle's [Managing Private Offers](https://docs.oracle.com/en-us/iaas/Content/Marketplace/manage-private-offers.htm). ## Can I report usage charges for Oracle entitlements? Yes. Fours aggregates each entitlement's pending usage and submits it to OCI hourly, and the value you report is a monetary amount rather than a quantity. Metered usage bills in addition to the offer's contract value. See [Usage Metering](/oracle-marketplace/usage-metering/). ## How often does Fours sync with Oracle? Automatically, **every hour**: listings, private-offer statuses, and derived entitlements are refreshed for every connected Oracle integration. You can also trigger a sync on demand from the **Integrations** page — for example, right after a buyer tells you they accepted an offer. ## Does Fours import Oracle disbursement or payout reports? Yes. Fours imports **disbursement report records** from the Oracle Marketplace Publisher API and converts them into revenue records, so Oracle payouts appear in Fours' revenue reporting alongside your other marketplaces. Note that Oracle only exposes roughly the **trailing 3 months** of disbursement data; Fours persists every imported record, so your history accumulates in Fours beyond Oracle's window, but backfills older than ~3 months cannot fetch anything new from Oracle. ## What are the contract document (EULA) requirements? The contract must be a real **PDF** file of **at most 1 MB**. If you provide it as a URL, the URL must be `https`. Other document formats (e.g. Word) are not converted automatically — export them to PDF first. ## Why does my offer stay in "Pending Create"? Fours sends the offer to Oracle and waits up to ~5 minutes for Oracle to confirm. If confirmation doesn't arrive in time, the offer stays in `Pending Create`. Re-submitting is safe: if the offer actually went live in Oracle, Fours adopts it instead of creating a duplicate; if it's a stale draft or a failed send, the old one is cleaned up and a fresh offer is created. ## Why did the integration verification fail? The most common causes: - The IAM service user lacks Marketplace Publisher permissions — check the [policy statements](/oracle-marketplace/integration/#2-grant-marketplace-publisher-permissions). - Wrong compartment OCID. - The user or API key was created moments ago — OCI can take ~2 minutes to replicate new credentials. Wait and retry. - The private key is passphrase-protected — **encrypted PEM keys are not supported**. Generate a key without a passphrase. ## How do I rotate the API signing key? Add a new API key to the service user in the OCI Console. The Fours console edits only the integration's **Display Name**, so either delete the integration and connect it again with the new private key and fingerprint, or update it through the Fours API, where a new private key replaces the stored one and leaving it empty keeps it. See [Edit Integration](/oracle-marketplace/integration/#edit-integration). --- Source: https://doc.fours.com/oracle-marketplace/usage-metering/ # Usage Metering :::note **Usage metering is enabled** (as of August 2026). Fours aggregates each entitlement's pending usage and submits it to Oracle Cloud Infrastructure hourly. Metered usage bills **in addition to** the offer's contract value, not instead of it. ::: ## Overview For usage-based products, Fours reports metered usage back to Oracle Cloud Marketplace (OCI) so buyers are billed for what they consume. You report usage to Fours with the same [Metering API](/metering/) you use for every other marketplace; Fours submits it to OCI on an hourly cadence. Oracle's usage model differs from the other marketplaces in one important way, described next. ## You report an amount, not a quantity :::warning For Oracle entitlements, the value you report **is the monetary amount** — not a quantity that Fours multiplies by a rate. Reporting `10` means **10 units of currency**, not 10 units of consumption. ::: OCI has no usage-dimension catalog and no per-dimension pricing, so there is no rate for Fours to apply. This means: - The value you send is forwarded to OCI as the charge, in the entitlement's currency. - Your own system owns the pricing calculation — compute the amount before you report it. - Decimal amounts are supported; the submitted amount is rounded to 5 decimal places (OCI's per-record limit), and an amount that rounds to zero is skipped. If you are porting an integration from AWS, Azure, or GCP, this is the one change you must make: send money where you previously sent a quantity. ## Usage keys are open Because there is no dimension catalog to validate against, Oracle accepts **any** usage key: - You may report against any key name you choose; it is registered on the entitlement the first time it is seen, and no configuration step is required in advance. - The key is submitted to OCI as the `usageDimensionName`. - An entitlement may accumulate at most **100 distinct usage keys**. This matches the maximum number of records OCI accepts in a single submission, so an entitlement that stays within the limit can always be reported. Beyond it, further new keys are rejected at ingestion. ## Commit and usage are separate An offer's commit or prepaid amount does **not** reduce reported usage. Fours forwards Oracle usage exactly as reported, with no commit, credit, or included-usage deduction applied. Track commit consumption separately from metered usage. ## Reporting cadence and windows - Fours aggregates each entitlement's pending usage and submits it to OCI **hourly**. - A submission carries at most **100 usage records** — one per non-zero usage key — which is OCI's own per-call limit. - A submission is **all-or-nothing**: if OCI rejects any record in the batch, the whole batch is rejected and no usage in it is recorded. - The window Fours tells OCI is the span of the **usage** — from the earliest to the latest usage timestamp in the batch — not the hour the run happened to execute in. Usage you report late, or backfill with an older timestamp, is therefore attributed to when it actually occurred. The report record you see in Fours carries its own, wider window based on when the usage arrived, so the two legitimately differ. - Zero-amount records are skipped — OCI rejects them, and a report containing only zero amounts is treated as a successful no-op. ## Duplicate protection Every record Fours submits carries an identifier derived **deterministically** from the usage it represents — the organization, the entitlement, the exact set of usage record groups in the submission, and the dimension key. Resubmitting the same set therefore produces the same identifiers, and OCI recognises the repeat and ignores it. Fours sends the same identity as OCI's `opc-retry-token` as well, a second, 24-hour backstop. If OCI reports that the usage was already recorded, Fours treats the submission as successful. That is what makes an **automatic** retry safe: it resends an identical submission. :::warning **A manual retry is only as safe as the group set it rebuilds.** Retrying a `REPORT_FAILED` usage record group returns it to `CREATED`, and the next hourly run re-aggregates **every** `CREATED` group for that entitlement. If any group has been created in the meantime — or you retry only part of a failed batch — the set differs from the original submission, so the derived identifiers differ and **OCI cannot recognise the resubmission as a repeat**. The risk case is a submission that actually reached OCI but was recorded as failed on Fours' side, for example a timeout or a lost acknowledgement. Reconcile in OCI before retrying — see [Confirm in OCI before a manual retry](#confirm-in-oci-before-a-manual-retry). ::: This is the sequence, and where the two retry paths diverge: ```d2 direction: down shape: sequence_diagram suger: "Fours" oci: "OCI" suger -> oci: "submitUsageRecords\nid = hash(org, entitlement, group set, dimension)" oci -> suger: "timeout — outcome unknown" auto: "Automatic retry (safe)" { suger -> oci: "same submission, same ids" oci -> suger: "already recorded → ignored, no second charge" } manual: "Manual retry (verify first)" { suger -> suger: "group returns to CREATED;\nnext run re-aggregates every CREATED group" suger -> oci: "different group set → different ids" oci -> suger: "not recognised as a repeat → CHARGED AGAIN" } ``` ### Confirm in OCI before a manual retry Fours keeps the full audit of every OCI submission on the usage record report, so you can check exactly what was sent before you resend it. Fetch the report with [List usage record reports](/api/list-usage-record-reports/) and read: | Field on the report | What it tells you | |---|---| | `info.oracleMeteringRequest.records[].id` | The exact OCI usage-record identifiers that were submitted. These are what OCI deduplicates on | | `info.oracleMeteringRequest.records[].amount` / `.usageDimensionName` | The amount and dimension in that submission | | `info.oracleMeteringRequest.idempotencyToken` | The `opc-retry-token` sent with the call | | `info.oracleMeteringResponse.opcRequestId` | OCI's `opc-request-id` for the call — quote this to Oracle Support when checking whether a submission landed | | `info.oracleMeteringResponse.error` | Why OCI rejected it, when it did | Then, in the OCI console, check the metered usage for the offer (`marketplaceOfferId`) over the report's usage window. Retry only when the usage is **absent** in OCI. If it is present, the submission landed and the `REPORT_FAILED` status is a lost acknowledgement — delete the group instead of retrying it, or contact [support@suger.io](mailto:support@suger.io) so the report can be reconciled without double-billing. Oracle's own rule is the same one: a retry of a usage record must reuse the original record ID, and a new ID must not be minted because a request timed out or failed retryably. See [Oracle's metered-usage record reference](https://docs.oracle.com/en-us/iaas/Content/Marketplace/usage-based-record-fwd.htm). ## Viewing reported usage Reported Oracle usage appears in the console under **Metering**, with `ORACLE` available in the partner filter on both the usage list and the aggregated reports. Failed submissions are visible there, and alerting covers usage that stays unreported. ## Prerequisites - A verified [Oracle Marketplace integration](/oracle-marketplace/integration). - An active entitlement derived from an accepted [private offer](/oracle-marketplace/private-offers). - The OCI IAM policy that permits usage submission must be granted in your partner tenancy. Without it, submissions are rejected with an authorization error. --- Source: https://doc.fours.com/oracle-marketplace/create-private-offer-api/ # Create a Private Offer via API ## Overview Create an Oracle Cloud Marketplace private offer programmatically with the Fours [`CreateOffer`](https://doc.fours.com/api/) endpoint. Fours creates the offer in OCI, attaches the contract document, and sends it to the buyer — the same flow the console runs, driven from your own system. The call is **asynchronous**. Fours validates the request, persists a `DRAFT` offer, returns it immediately, and then works with OCI in the background. The offer's real status arrives through the hourly marketplace sync; poll the offer to follow it. ## Prerequisites - An [Oracle Marketplace integration](/oracle-marketplace/integration) connected at the organization level. - The product **synced into Fours** from your OCI listing — Fours resolves the listing OCID from the product's external ID, so a product created by hand will not work. See [List a Product](/oracle-marketplace/list-product). - The buyer's **tenancy OCID**, or an existing Fours buyer record whose partner is `ORACLE`. - A contract document (EULA) reachable over `https`, or already uploaded to Fours. - An access token — see [OAuth App](/settings/oauth-app). ## Endpoint ``` POST https://api.suger.cloud/org/{orgId}/offer ``` | | | |---|---| | **Operation ID** | `CreateOffer` | | **Auth** | `Authorization: Bearer ` | | **Body** | A `WorkloadOffer` object | | **Success** | `200` with the created `WorkloadOffer` | ## Request fields ### Top level | Field | Required | Notes | |-------|----------|-------| | `partner` | ✅ | `ORACLE` | | `service` | ✅ | `MARKETPLACE` | | `offerType` | ✅ | `PRIVATE`. Oracle supports no other type — `CPPO_OUT` and channel offers are rejected. | | `productID` | ✅ | Fours product ID. Must be an Oracle-synced product carrying the listing OCID. | | `name` | ✅ | Becomes the offer's `displayName` in OCI. Oracle rejects an empty name. | | `buyerID` | ⬜ | A Fours buyer to link. Required only if you omit `info.oracleOffer.buyerTenancyOCID`; the buyer must belong to partner `ORACLE`. | ### `info` | Field | Required | Notes | |-------|----------|-------| | `info.eulaUrl` | ✅ | The contract document. Either an `https` URL that Fours fetches server-side, or the key of a file you uploaded to Fours. **Plain `http` is rejected.** Must resolve to a **PDF of at most 1MB** (Oracle's per-attachment limit). | | `info.additionalEulaUrls` | ⬜ | Further contract documents, same format and limits as `info.eulaUrl`. Each becomes its **own attachment** on the OCI offer (unlike AWS, where additional EULAs are merged into one document). | | `info.currency` | ⬜ | ISO-4217 code. Defaults to `USD`. | | `info.commits` | ⬜ | The offer's line items. Their total becomes the offer's `totalAmount` — see [Pricing](#pricing) below. | ### `info.oracleOffer` Oracle-specific fields, an `OracleMarketplaceOffer` object. | Field | Required | Notes | |-------|----------|-------| | `sellerPrimaryContact` | ✅ | Must include `email`. Oracle fails the send with `SELLER_INFORMATION_IS_NULL` without it. | | `buyerPrimaryContact` | ✅ | Must include `email`. Oracle rejects the send without a buyer contact. | | `buyerTenancyOCID` | ✅* | The buyer's OCI tenancy OCID. *Required unless you set `buyerID` to a linked Oracle buyer; when both are present, this field wins. | | `buyerCompanyName` | ⬜ | Buyer's company name. | | `description` | ⬜ | Offer description shown in OCI. | | `duration` | ⬜ | ISO-8601 contract length (`P1Y`, `P6M`, `P30D`, …), measured from `timeStartDate` — or from the creation time when billing starts on acceptance. Defaults to **`P1Y`** (one year). Oracle accepts only day-based durations, so Fours converts the value to days before sending: `P1Y` goes out as `P365D` (or `P366D` across a February 29). Oracle's maximum total contract length is **375 days**, so `P2Y` and `P3Y` are rejected at send time. | | `timeEndDate` | ⬜ | An explicit end date, used instead of `duration` when both are set. Fours converts it to a day count from the start, rounding partial days up. Must be after `timeStartDate`, or in the future when billing starts on acceptance. | | `timeStartDate` | ⬜ | When billing starts. Omit it to start billing when the buyer accepts — the default. | | `timeAcceptBy` | ⬜ | Deadline for the buyer to accept. Defaults to **30 days out**, or to the day before `timeStartDate` if that is sooner. Must be before `timeStartDate` — Oracle rejects the send otherwise. | Contact objects take `firstName`, `lastName`, and `email`. :::note Fields such as `offerID`, `offerStatus`, `pricing`, `timeAccepted`, `timeOfferEnd`, `resourceBundles`, `resolvedProductIDs` and `lifecycleDetails` (Oracle's reason when a send fails) are **read-only** — Fours populates them from OCI. Sending them has no effect. In particular, `pricing.totalAmount` cannot be set directly: the offer's amount comes exclusively from `info.commits` (see [Pricing](#pricing)). ::: ## Pricing Oracle offers are sent to OCI with a single `ONE_TIME` billing cycle and one total amount. Fours computes that total from `info.commits`: ``` totalAmount = round( Σ (commit.rate × commit.quantity) ) ``` - A commit with no `quantity` counts as `1`. - The sum is **rounded** to the nearest whole unit of currency, never truncated. - Omit `info.commits` entirely and the offer is created with a total of `0` — which Oracle rejects at send time, because its minimum contract value is 10,000 USD. :::note For Oracle this total is the whole of the offer's pricing — OCI has no dimension catalog and no per-dimension rate card, so the individual commit lines are not sent to Oracle, only their sum. Usage on the resulting entitlement is billed separately and is also reported as a monetary amount; see [Usage Metering](/oracle-marketplace/usage-metering). ::: :::warning **Oracle's contract limits are enforced by Oracle, not by Fours.** Fours sends the `info.commits` total and the `duration` you submit without imposing a minimum or maximum of its own, so an offer outside Oracle's accepted range is rejected at send time and lands in `CREATE_FAILED`. Oracle publishes a **minimum contract value of 10,000 USD** (or the equivalent in another supported currency) and a **maximum total contract length of 375 days** — one year plus 10 days. An offer with no `info.commits`, and a `duration` of `P2Y` or `P3Y`, fall outside those limits. See Oracle's [Managing Private Offers](https://docs.oracle.com/en-us/iaas/Content/Marketplace/manage-private-offers.htm). ::: ## Example Always include `info.commits`. Oracle requires a **minimum contract value of 10,000 USD**, so an offer whose commits sum to less than that — including an offer with no `info.commits` at all, which Fours sends as a `$0` total — is rejected by Oracle at send time and ends up as `CREATE_FAILED`. Usage reported on the resulting entitlement is billed **in addition to** this contract value, not instead of it; see [Usage Metering](/oracle-marketplace/usage-metering/). ```shell curl -L -X POST 'https://api.suger.cloud/org/YOUR_ORG_ID/offer' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ --data-raw '{ "partner": "ORACLE", "service": "MARKETPLACE", "offerType": "PRIVATE", "productID": "KVvfb0Vhv", "name": "Acme Corp - Annual Contract 2026", "info": { "currency": "USD", "eulaUrl": "https://acme.example.com/legal/eula-2026.pdf", "additionalEulaUrls": [ "https://acme.example.com/legal/annex-a-2026.pdf" ], "commits": [ { "name": "Platform subscription", "rate": 50000, "quantity": 1 } ], "oracleOffer": { "description": "Annual platform subscription for Acme Corp.", "duration": "P1Y", "buyerTenancyOCID": "ocid1.tenancy.oc1..aaaaaaaaexamplebuyertenancy", "buyerCompanyName": "Acme Corp", "buyerPrimaryContact": { "firstName": "Ada", "lastName": "Lovelace", "email": "ada@acme.example.com" }, "sellerPrimaryContact": { "firstName": "Grace", "lastName": "Hopper", "email": "grace@yourcompany.com" } } } }' ``` The response is the persisted offer. Note `status` — it is the Fours record, not yet the OCI state: ```json { "id": "FIwCbefqu", "organizationID": "YOUR_ORG_ID", "partner": "ORACLE", "service": "MARKETPLACE", "offerType": "PRIVATE", "productID": "KVvfb0Vhv", "buyerID": "gHYis9RKU", "name": "Acme Corp - Annual Contract 2026", "status": "DRAFT", "info": { "currency": "USD", "visibility": "PRIVATE", "deliveryMethod": "PRIVATE" } } ``` Keep the returned `id`. It is the Fours offer ID used for every follow-up call, and it doubles as the idempotency token for the OCI create — a retried submission will not produce a duplicate buyer-visible offer. ## Track the offer ```shell curl -L -X GET 'https://api.suger.cloud/org/YOUR_ORG_ID/offer/FIwCbefqu' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` Immediately after the `200`, Fours moves the offer to `PENDING_CREATE` while it creates the offer in OCI, attaches the contract, and sends it — about five minutes. Once OCI has the offer, `info.oracleOffer.offerID` holds the private-offer OCID and `info.oracleOffer.offerStatus` holds Oracle's raw status. Fours maps that raw status onto its own: | Oracle `offerStatus` | Fours `status` | |---|---| | `DRAFT` | `DRAFT` | | `PENDING_MARKETPLACE` | `PENDING_MARKETPLACE_APPROVAL` | | `PENDING_BUYER` | `PENDING_ACCEPTANCE` | | `ACCEPTED` | `ACCEPTED` | | `ACTIVE` | `ACTIVE` | | `ENDED`, `EXPIRED` | `EXPIRED` | | `FAILED_SEND`, `FAILED_ACCEPT` | `CREATE_FAILED` | When Oracle rejects the send, `info.oracleOffer.lifecycleDetails` carries Oracle's reason — for example `DURATION_IS_INVALID` or `TIME_ACCEPT_BY_IS_INVALID` — and the offer's `metaInfo.errorMessages` records it as `… send rejected (FAILED_SEND: )`. The Fours-side lifecycle, from the synchronous response through the hourly sync: ```d2 direction: down draft: "DRAFT\nreturned immediately by CreateOffer" pendingCreate: "PENDING_CREATE\nFours creates the offer in OCI,\nattaches the contract, sends it\n(~5 min to confirm)" pendingMkt: "PENDING_MARKETPLACE_APPROVAL\nOracle: PENDING_MARKETPLACE" pendingAcc: "PENDING_ACCEPTANCE\nOracle: PENDING_BUYER" accepted: "ACCEPTED\nOracle: ACCEPTED" active: "ACTIVE\ncontract in effect" entitlement: "Entitlement derived in Fours\nACTIVE at once without a timeStartDate;\nelse PENDING_START until timeStartDate" expired: "EXPIRED\nOracle: ENDED / EXPIRED" failed: "CREATE_FAILED\nOracle: FAILED_SEND / FAILED_ACCEPT" pendingCancel: "PENDING_CANCEL\nonly before the buyer accepts" cancelSuccess: "CANCEL_SUCCESS\nwithdrawn in Oracle" cancelFailed: "CANCEL_FAILED\nstill live to the buyer" draft -> pendingCreate: "200 returned, Fours works with OCI" pendingCreate -> pendingMkt: "Oracle reports PENDING_MARKETPLACE" pendingCreate -> pendingAcc: "Oracle reports PENDING_BUYER" pendingCreate -> failed: "send rejected" pendingMkt -> pendingAcc: "Oracle approves the offer" pendingAcc -> accepted: "buyer accepts in the Oracle Cloud Console" pendingAcc -> expired: "timeAcceptBy passes unaccepted" pendingAcc -> failed: "acceptance fails" pendingMkt -> pendingCancel: "cancel" { style.stroke-dash: 4 } pendingAcc -> pendingCancel: "cancel" { style.stroke-dash: 4 } pendingCancel -> cancelSuccess pendingCancel -> cancelFailed accepted -> entitlement: "entitlement derived on acceptance" accepted -> active: "timeStartDate reached" active -> expired: "contract ends" ``` As soon as the offer is `ACCEPTED`, Fours derives an **entitlement** for the buyer — `ACTIVE` straight away when the offer has no `timeStartDate` (billing starts on acceptance); otherwise `PENDING_START` until the offer's start date, `ACTIVE` from then on. Buyers are deduped by tenancy OCID, so repeat deals with the same customer attach to the same buyer record. ## Withdraw an offer ```shell curl -L -X POST 'https://api.suger.cloud/org/YOUR_ORG_ID/offer/FIwCbefqu/cancel' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` Oracle allows withdrawing any offer the buyer has not yet accepted, so this is valid while the offer is `PENDING_ACCEPTANCE` or `PENDING_MARKETPLACE_APPROVAL`. Once accepted, it can no longer be withdrawn. ## Validation errors These are returned as `400` before anything is created in OCI, so a rejected request never leaves an orphaned draft in your marketplace account. | Message | Fix | |---|---| | `invalid offer type ... to create private offer in Oracle Marketplace` | Set `offerType` to `PRIVATE`. | | `offer name is required` | Set `name`. | | `info.eulaUrl is required` | Provide a contract document. | | `info.eulaUrl ... must be an https URL` | Use `https`, not `http`. | | `info.oracleOffer.sellerPrimaryContact (with email) is required` | Add the seller contact with an email. | | `info.oracleOffer.buyerPrimaryContact (with email) is required` | Add the buyer contact with an email. | | `buyer tenancy OCID is required ...` | Set `info.oracleOffer.buyerTenancyOCID`, or link an Oracle buyer via `buyerID`. | | `info.oracleOffer.timeAcceptBy (...) must be before timeStartDate (...)` | Move `timeAcceptBy` before `timeStartDate`, or omit it to take the default. | | `info.oracleOffer.timeEndDate (...) must be after timeStartDate (...)` | Move `timeEndDate` after the start, or send a `duration` instead. | | `info.oracleOffer.timeEndDate (...) must be in the future when billing starts on acceptance` | Use a future end date, or send a `duration` instead. | | `info.oracleOffer.duration "..." is not a valid ISO-8601 period ...` | Send a period such as `P1Y`, `P6M` or `P30D`. | | `info.oracleOffer.duration "..." must be a non-zero period` | Send a positive period, or omit `duration` for the one-year default. | Two further checks need OCI context and therefore surface after the API has returned, as a `CREATE_FAILED` offer rather than a `400`: - The product must resolve to an Oracle listing OCID. - A linked `buyerID` must belong to partner `ORACLE`; a buyer imported from another marketplace is refused. --- Source: https://doc.fours.com/oracle-marketplace/report-usage-api/ # Report Usage via API ## Overview :::note **Usage metering is enabled** (as of August 2026). Fours aggregates each entitlement's pending usage and submits it to Oracle Cloud Infrastructure hourly. Metered usage bills **in addition to** the offer's contract value, not instead of it. ::: You report usage to **Fours**, against a Fours entitlement; Fours aggregates pending usage and submits it to OCI on an **hourly** cadence. The endpoints are the same generic [Metering API](/metering/) used for every marketplace — this page documents the Oracle-specific field semantics. The two rules that make Oracle different from AWS/Azure/GCP: 1. **The value you report is a monetary amount, not a quantity.** OCI has no dimension catalog and no per-dimension rate card, so Fours applies no rate — `"records": {"usage": 10}` bills **10 units of the entitlement's currency**. 2. **Usage keys are open.** Any key name is accepted and auto-registered on the entitlement the first time it is seen — no dimension configuration in advance. An entitlement may accumulate at most **100** distinct keys. ## Endpoints | Purpose | Endpoint | Operation | |---|---|---| | Report one group (deduplicated by `id`) | `POST /org/{orgId}/entitlement/{entitlementId}/usageRecordGroup` | `ReportUsageRecordGroup` | | Report a batch (no dedup key) | `POST /org/{orgId}/batchCreateUsageRecordGroups` | `BatchReportUsageRecordGroups` | | List groups (check status / reported time) | `GET /org/{orgId}/usageRecordGroup` | `ListUsageRecordGroups` | Auth: `Authorization: Bearer ` — see [OAuth App](/settings/oauth-app). Prefer the single-group endpoint with your own `id` for anything automated: the `id` is the idempotency key, so a retried request cannot double-report. The batch endpoint carries no dedup key. Supporting operations (aggregate, validate, retry, delete) are documented in the generic [Metering API](/metering/) reference. ## Request fields — `CreateUsageRecordGroupParams` | Field | Required | Type | Notes | |-------|----------|------|-------| | `id` | ⬜ | string (≤36 chars) | Your idempotency key, typically a UUID. Reporting the same `id` again within **15 days** is rejected with a `400` instead of double-billing. Omitted → Fours generates one (and you lose dedup protection). | | `entitlementID` | ✅ | string | The Fours entitlement to bill. Must belong to the org, partner `ORACLE`. In the single-group endpoint this comes from the URL path instead. | | `records` | ✅ | map<string, number> | **The data.** Key → monetary amount (see dictionary below). | | `timestamp` | ⬜ | RFC-3339 date-time | When the usage was **generated** (not when it is reported). Defaults to the report time. | | `billableRecords` | ❌ | `MeteringUsageRecord[]` | **Not supported for Oracle.** This is the Metering API v2 field; Oracle reports **v1 `records` only**. A group reported with `billableRecords` instead of `records` is accepted at ingestion but skipped by the hourly OCI submission — the usage is never billed. Always use `records`. | | `metaInfo` | — | object | **Read-only.** Populated by Fours (origin records, source, invoice linkages). Sending it has no effect. | | `usageAllocations` | — | map | AWS-only feature; ignored for Oracle. | ### `records` — the field data dictionary `records` is a flat map of usage key → amount: ```json "records": { "usage": 12.5, "api-calls": 3.99 } ``` | Aspect | Rule | |---|---| | **Key** (map key) | Any name you choose — Oracle usage keys are **open**. The key is auto-registered on the entitlement on first use and becomes the OCI `usageDimensionName`. Use stable, human-readable names (`usage`, `api-calls`, `gb-processed`). | | **Key cap** | At most **100 distinct keys** per entitlement, matching OCI's per-submission record cap. The 101st new key is rejected at ingestion with a `usage dimensions … exceeding the 100 cap` error. | | **Value** (map value) | The **monetary amount to bill**, in the entitlement's currency — not a consumption quantity. Decimals are supported; the submitted amount is **rounded to 5 decimal places** (OCI's per-record limit), and an amount that rounds to zero is skipped. | | **Zero values** | Skipped — OCI rejects zero-amount records. A group whose values are *all* zero is rejected at ingestion (`400: all the quantity of usage records are zero`). | | **Negative values** | Rejected. Usage can only add charges; corrections go through Oracle support. | | **Commit interaction** | None. Amounts are forwarded as-is; no commit/credit/included-usage deduction is applied. | ## Response fields — `MeteringUsageRecordGroup` | Field | Type | Notes | |-------|------|-------| | `id` | string | The group's ID (yours, or generated). Used for retry/delete and as the dedup key. | | `organizationID` / `entitlementID` / `buyerID` | string | Ownership. `buyerID` is resolved from the entitlement. | | `partner` | string | `ORACLE`. | | `records` | map | The records as stored (after any dimension mapping; for Oracle open keys this equals what you sent). | | `status` | string | Lifecycle state — see below. | | `creationTime` / `lastUpdateTime` | date-time | Bookkeeping. | | `usageRecordReportID` | string | Set once the hourly job folds the group into an OCI submission — joins to `GET /org/{orgId}/usageRecordReport`. | | `reportedTime` | date-time \| null | When the group was reported to OCI. `null` until then. | | `metaInfo.originRecords` | map | The records exactly as you reported them, before any conversion. | | `metaInfo.timestamp` | date-time | The usage-generation timestamp you supplied. | | `metaInfo.source` | string | `API` for groups created this way. | ### Status lifecycle | Status | Meaning | |---|---| | `CREATED` | Accepted and queued; the hourly job will pick it up. | | `REPORTED` | Folded into an OCI submission; `usageRecordReportID` and `reportedTime` are set. | | `REPORT_FAILED` | The OCI submission failed. Inspect, then `retry` (moves it back to `CREATED`). | | `INVALID` | Rejected by validation after creation. | | `DELETED` | Hard-deleted via the delete endpoint. | :::warning Automatic retries inside one submission are duplicate-protected — the OCI record identifiers are derived from the submission's contents, so an identical resubmission dedupes. A **manual `retry` is not** equivalent: it returns the group to `CREATED`, and the next run re-aggregates every `CREATED` group for the entitlement. If that set differs from the failed submission, the derived identifiers differ and OCI cannot recognise the repeat. Before retrying a `REPORT_FAILED` group, confirm in OCI that the usage was not already recorded — the report's `info.oracleMeteringRequest.records[].id` and `info.oracleMeteringResponse.opcRequestId` tell you exactly what was submitted. See [Usage Metering — confirm in OCI before a manual retry](/oracle-marketplace/usage-metering/#confirm-in-oci-before-a-manual-retry). ::: ## What Fours submits to OCI Each key/amount pair becomes one record in OCI's `submitUsageRecords` call (at most 100 records per call, all-or-nothing): | OCI field | Sourced from | |---|---| | `id` | Derived deterministically from the organization, entitlement, the submitted group-ID set, and the dimension key — so resubmitting the same set is idempotent. A different group set yields a different `id`. | | `marketplaceOfferId` | The entitlement's Oracle private-offer OCID. | | `usageDimensionName` | The `records` map key (the literal `usage` when no specific dimension applies). | | `amount` | The `records` map value, at full precision. | | `currencyCode` | The entitlement's currency. | | `timeUsageStarted` / `timeUsageEnded` | The span of the **usage itself** — the earliest and latest usage timestamps across the groups in the report, not the report run's own window. | :::info The report's own start/end is wider on purpose The `startTime` / `endTime` on the Fours usage-record **report** are derived from when groups were *created* and are deliberately wider than the window sent to OCI: they exist to track which groups a run claimed. OCI is told the span of the usage, so consumption is attributed to when it actually happened. Expect the two to differ — especially when you backfill usage with an older `timestamp`. ::: ## Example Report one group, idempotent by `id`: ```shell curl -L -X POST 'https://api.suger.cloud/org/YOUR_ORG_ID/entitlement/YOUR_ENTITLEMENT_ID/usageRecordGroup' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ --data-raw '{ "id": "2f9c1e58-9a1b-4c7e-b1d2-8f3a5c6d7e90", "records": { "usage": 12.5, "api-calls": 3.99 }, "timestamp": "2026-08-05T00:00:00Z" }' ``` Response (trimmed): ```json { "id": "2f9c1e58-9a1b-4c7e-b1d2-8f3a5c6d7e90", "organizationID": "YOUR_ORG_ID", "partner": "ORACLE", "entitlementID": "YOUR_ENTITLEMENT_ID", "buyerID": "gHYis9RKU", "records": { "usage": 12.5, "api-calls": 3.99 }, "status": "CREATED", "metaInfo": { "originRecords": { "usage": 12.5, "api-calls": 3.99 }, "timestamp": "2026-08-05T00:00:00Z", "source": "API" } } ``` Report a batch — the body is an **array**; each entry needs `entitlementID` + `records` (the response is the array of created groups, one per entry, with generated `id`s): ```shell curl -L -X POST 'https://api.suger.cloud/org/YOUR_ORG_ID/batchCreateUsageRecordGroups' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ --data-raw '[ { "entitlementID": "YOUR_ENTITLEMENT_ID", "records": { "usage": 0.75 }, "timestamp": "2026-08-05T00:00:00Z" }, { "entitlementID": "ANOTHER_ENTITLEMENT_ID", "records": { "api-calls": 4.2 } } ]' ``` Since batch entries carry no caller-supplied `id`, a retried batch request **re-creates** the groups — use the single-group endpoint when you need idempotency. ## Errors | Response | Cause / fix | |---|---| | `400: the record id … has already been reported in the last 15 days` | A group with the same `id` was reported within the 15-day dedup window — this is the dedup working. Do not resend with a new `id` unless the usage is genuinely new. | | `400: all the quantity of usage records are zero` | Every value in `records` is `0`. Zero-amount records are never billable; skip the report instead. | | `400: … usage dimensions, exceeding the 100 cap …` | The report would push the entitlement past 100 distinct usage keys. Reuse existing keys, or prune the entitlement's registered dimensions. | | `400` naming the entitlement | The entitlement doesn't exist, isn't in this org, or isn't in a reportable state. | --- Source: https://doc.fours.com/oracle-marketplace/ # Oracle Marketplace Oracle Cloud Marketplace is the narrowest integration in this documentation, and knowing its boundaries up front will save you a planning cycle. Fours does not create Oracle listings — you publish them in the Oracle Cloud Marketplace Partner Portal and Fours imports them, hourly, as products you can transact against. Only **SaaS** listings sync; container images, machine images, stacks, and Helm charts are skipped. Buyers are identified by their tenancy OCID, and every offer carries a contract document as a PDF. What Fours adds is the private offer motion: a single total contract value in USD over a fixed term, sent from the console and tracked through acceptance. Pricing is one-time by design — there are no installments, and usage metering is a separate, entitlement-level capability that bills on top of the contract value. Connecting is organization-wide and uses an OCI API signing key belonging to a dedicated, least-privilege IAM user in your tenancy. ## Connect and start transacting 1. **[Integration](/oracle-marketplace/integration/)** — create the least-privilege IAM user, grant it Marketplace Publisher permissions, and connect with an unencrypted API signing key. 2. **[List Product](/oracle-marketplace/list-product/)** — how the hourly sync imports your published SaaS listings as Fours products, how Oracle lifecycle states map to Fours product statuses, and how to force a sync after publishing. 3. **[Private Offers](/oracle-marketplace/private-offers/)** — send an offer to a buyer's tenancy: total contract value, a term within Oracle's 375-day maximum, and the EULA PDF Oracle requires. ## Meter usage and troubleshoot - **[Usage Metering](/oracle-marketplace/usage-metering/)** — how Oracle metering behaves, and the one rule that differs from every other cloud: you report a monetary amount, not a quantity. - **[FAQ](/oracle-marketplace/faq/)** — short answers to the questions that come up in practice, including why an offer can sit in Pending Create, what makes integration verification fail, and how to rotate the API signing key. ## Drive it from your own systems - **[Create a Private Offer via API](/oracle-marketplace/create-private-offer-api/)** — the request shape for sending an Oracle offer programmatically, including the EULA fields and the additional-document option the console form does not expose. - **[Report Usage via API](/oracle-marketplace/report-usage-api/)** — submit metered usage without the console, and the window and per-call record limits that apply. ## Scope and limits :::info **SaaS listings only.** Other Oracle Marketplace listing types are not synced and cannot be used in offers created through Fours. **Private offers are one-time contract value in USD** — whole dollars, a contract length you set in days, months or years (or as an end date), and no installment plans. Oracle requires a minimum of **10,000 USD** and a maximum total contract length of **375 days**, and rejects anything outside those at send time. **Usage metering is enabled** (as of August 2026). Fours submits each entitlement's pending usage to OCI hourly, and metered usage bills on top of the contract value. **Passphrase-protected private keys are not supported.** Generate the API signing key without one. This section has no revenue guide. The FAQ above is where to look for what Fours pulls from Oracle's disbursement reports and the roughly three-month window Oracle exposes. ::: --- Source: https://doc.fours.com/salesforce-app/salesforce-app-authentication-security/ # Authentication & Security Fours connects to your Salesforce org via the **OAuth 2.0 Authorization Code flow with PKCE** ([RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)). The Fours External Client App is configured for compliance with Salesforce's Connected App security requirements. ## What Fours never sees - Your Salesforce user's **password**. The user authenticates directly with Salesforce; only an authorization code is returned to Fours. - No **static API key or long-lived bearer token** for your org. Every API call uses a short-lived access token. - Fours' **client secret** stays on Fours' backend and is never exposed to the browser. ## Mandate-compliant authentication The Fours External Client App enforces the four security controls required by Salesforce's May 2026 mandate. These are configured at the app level and travel with the managed package install — you don't configure them per-org. | Control | What it does | | :-- | :-- | | **PKCE** ([RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)) | The browser-side authorization code is bound to a one-time `code_verifier` held only by Fours' backend. A stolen authorization code cannot be redeemed without it. | | **Refresh Token Rotation** | Every refresh issues a new RT and invalidates the prior one. A leaked RT becomes useless on first reuse, and Salesforce detects reuse and revokes the entire grant. | | **Idle TTL: 30 days** | A refresh token unused for 30 days is automatically revoked. Fours' 30-minute cron keeps the timer well under this limit. | | **IP Allowlist** | Refresh requests are only accepted from Fours' published NAT egress IPs. Contact support for the current list. | ## Authorization flow (first-time connect) 1. **Browser redirect** to Salesforce with a PKCE `code_challenge` and signed state. 2. **User consent** at Salesforce (SSO/MFA per your org policy). 3. **Authorization code** returned to Fours' callback. 4. **Server-side token exchange** with `code_verifier`, returning an access token and refresh token. Neither passes through the browser. 5. **Credentials stored** in AWS Secrets Manager (KMS-encrypted, IAM-scoped). The line between the browser and the backend is what the flow is built around: the browser only ever carries the authorization code, and the `code_verifier` that redeems it never leaves Fours' backend. ```d2 shape: sequence_diagram admin: "Your admin\n(browser)" sf: "Salesforce" suger: "Fours backend" vault: "AWS Secrets Manager" admin -> sf: "1. redirect with code_challenge + signed state" sf -> admin: "2. consent (SSO / MFA per your org policy)" admin -> suger: "3. authorization code on the callback" suger -> sf: "4. token exchange with code_verifier\n(server to server, never in the browser)" sf -> suger: "access token + refresh token" suger -> vault: "5. store credentials (KMS-encrypted, IAM-scoped)" refresh: "Automatic refresh — every ~2h, 3 min before expiry" { suger -> vault: "read current refresh token" suger -> sf: "refresh" sf -> suger: "new access token + rotated refresh token\n(the previous one is invalidated)" suger -> vault: "persist the rotated pair" } revoke: "Revocation" { admin -> sf: "revoke in Salesforce — all tokens die,\nFours' next call is rejected" admin -> suger: "delete in Fours Console — the stored secret is removed" suger -> vault: "delete secret" } ``` ## Automatic refresh Access tokens are ~2 hours by default and can be longer depending on your org's Session Policy. Before they expire (3-minute safety buffer), Fours exchanges the refresh token for a new pair and persists the rotated credentials to AWS Secrets Manager. The refresh flow is coordinated across Fours' infrastructure to remain fully compatible with Refresh Token Rotation. ## Token storage | Credential | Storage | Encryption | | :-- | :-- | :-- | | Access token, refresh token, client secret | AWS Secrets Manager | AES-256 via AWS KMS | | Instance URL, expiration, username | Application database | Provider-managed at rest | IAM-scoped access, CloudTrail-audited reads. No standing employee access. ## Scopes and least privilege Fours requests only the OAuth scopes needed for features you've opted into. Inside your Salesforce org, the **Integration User's Profile and Permission Sets** are the authoritative access boundary — they apply regardless of OAuth scope. See [Permission Sets](/salesforce-app/salesforce-app-permission-sets/). ## Required OAuth policy settings (admin) The Fours External Client App ships with mandate-compliant defaults. The settings below are the ones your admin still controls. Open them at **Setup → External Client App Manager → Suger → Policies tab → Edit**. | Setting | Required value | Why | | :-- | :-- | :-- | | **Permitted Users** | `Admin approved users are pre-authorized` **or** `All users may self-authorize` | With pre-authorized, you must list the Integration User's profile or permission set under **Selected Profiles/Permission Sets**, otherwise OAuth fails with *"Not approved for access"*. | | **IP Relaxation** | `Relax IP restrictions` **or** allowlist Fours' egress IPs | If you `Enforce IP restrictions`, add Fours' egress IPs to **Profile → Login IP Ranges** and (if your org enforces it) **Network Access → Trusted IP Ranges**. | | **High Assurance Session Required** | Off | An MFA-verified session can't be satisfied by a server-to-server integration. | | **Selected Profiles / Permission Sets** | Must include the Integration User's profile or an assigned permission set | Only enforced when `Permitted Users = Admin approved`. | > Tightening these on a live integration may require reconnecting it: in **Fours Console → Settings → Integrations**, open the **⋯** menu on the verified Salesforce card and choose **Reconnect**. Reconnect replaces the stored credential and keeps the integration's settings. Fours asks Salesforce for a fresh sign-in, pre-filled with the connected user — sign in as that user. When the confirmation dialog names the connected user and you sign in as someone else, Fours cancels the reconnect and nothing changes, unless you checked **Change the connected Salesforce user**. See [Reconnect the integration](/integrations/salesforce/#reconnect-the-integration). ## Transport security All Fours ↔ Salesforce traffic — authorize, callback, `/token`, introspect, REST — uses **TLS 1.2 or higher**. ## Revocation and deletion - **Revoke in Salesforce**: invalidates all tokens; Fours' next call is rejected. - **Delete in Fours Console**: removes the AWS Secrets Manager secret; no further calls to your org. See the [Salesforce Integration Setup Guide](/integrations/salesforce/#removing-the-integration) for step-by-step removal instructions. ## Summary | Property | Value | | :-- | :-- | | OAuth flow | Authorization Code + PKCE (RFC 6749, RFC 7636) | | Refresh Token Rotation | Enforced | | Idle TTL | 30 days | | IP allowlist | Enforced (Fours egress IPs) | | Access token lifetime | ~2h (per your Session Policy) | | Credential storage | AWS Secrets Manager (KMS, IAM, CloudTrail) | | Transport | TLS 1.2+ | | Access boundary | Profile + Permission Sets on the Integration User | | Revocation | Immediate, from either side | --- Source: https://doc.fours.com/salesforce-app/salesforce-app-crm-enrichment/ # CRM Enrichment CRM Enrichment automatically populates Salesforce records with intelligence signals from Fours — engagement scores and marketplace metrics across AWS, Azure, and GCP — so your sales team gets actionable insights inside Salesforce without leaving the CRM. --- ## Overview With CRM Enrichment, you can: - **Automatically populate CRM fields** with intelligence signals (engagement scores, marketplace metrics) - **Configure multiple record types** (e.g., Opportunities, Accounts) with different enrichment rules - **Use SOQL queries** to target specific records for enrichment - **Map intelligence fields** to custom Salesforce fields ## Prerequisites Before configuring enrichment, ensure you have: 1. **Custom fields created** in Salesforce to store the intelligence data. 2. **Integration User permissions** on the permission set used by Fours: - **Field-level read and edit access** on every custom field you add for enrichment. - **Write access** to the records you plan to enrich. The simplest way to grant this is the **Modify All Records** permission on each object (e.g., Account, Opportunity) — but this is not strictly required. If the Integration User already has edit access to the relevant records through ownership or sharing rules, that is sufficient. Records the Integration User cannot write to are skipped with a per-record error; the rest of the batch still succeeds. ## Creating Custom Fields in Salesforce You need to create custom fields in Salesforce to store the intelligence signals. For each signal you want to sync: 1. Go to **Setup** → **Object Manager** → Select your object (e.g., Account, Opportunity) > Object Manager page in Salesforce Setup 2. Click **Fields & Relationships** → **New** > Fields and Relationships New button in Salesforce 3. Choose the appropriate field type. Fours supports the following Salesforce field types as enrichment destinations: - **Text** or **Text Area** — works for any signal (recommended default) - **Picklist** — works for categorical signals only (the engagement scores). The picklist values you define **must exactly match** the values Fours writes (case-sensitive). For the AWS/Azure/GCP Engagement Score signals, define the picklist with exactly these active values: `Low`, `Medium`, `High`. Any other casing or wording (e.g. `low`, `LOW`, `Tier 1`) will cause writes to fail. If Fours cannot determine an engagement score for a record (no data available), the field is written with an empty value — if your picklist has "Restrict picklist to the values defined in the value set" enabled (Salesforce's default), those writes will be rejected. To accept blanks, either disable the restriction or use a Text field instead. > Field type selection when creating a custom Salesforce field 4. Enter a **Field Label** (e.g., "Azure Engagement Score") > Field Label entry when creating a custom Salesforce field 5. Configure field-level security to allow the Integration User to read and write 6. Add the field to your page layouts as needed > **Note on multi-picklist fields:** Multi-picklist destinations are not supported. Fours signals produce single values, so map them to single picklist or text fields instead. ## Configuring Enrichment 1. Navigate to **Fours Console** → **Settings** → **Integrations** → **Salesforce** 2. Click **Edit** to open the integration settings 3. Go to the **Enrichment** tab 4. Click **Add CRM Record** to create a new enrichment rule > Add CRM Record button in Fours enrichment configuration For each configuration, specify: | Setting | Description | |---------|-------------| | **Record Type** | The Salesforce object to enrich (e.g., Opportunity, Account) | | **Query** | SOQL query to filter which records to enrich | | **Field Mappings** | Map intelligence fields to your custom Salesforce fields | | **Refresh Existing** | Controls when previously enriched records are refreshed: **Never**, **Immediately**, or **Every N days** (default: 30 days) | | **Max Records Per Sync** | Maximum number of records to process per sync run (default: 10,000, maximum: 50,000, minimum: 1,000) | After entering your query, click **Validate Query** to verify it is valid and see how many records match. This helps ensure your enrichment rule targets the right set of records before saving. ## Available Intelligence Fields Intelligence signals are derived from multiple data sources: - **Cloud partner data** — Engagement scores sourced directly from cloud partner programs (e.g., AWS Partner Network, Azure Partner Center, Google Cloud Partner Network). - **Marketplace activity** — Public marketplace metrics such as listing counts, review counts, and purchase history across AWS, Azure, and GCP marketplaces. The following intelligence signals can be mapped to your CRM fields: **AWS Signals** - AWS Engagement Score - AWS Marketplace Count - AWS Marketplace Review Count - AWS Marketplace Purchase Count **Azure Signals** - Azure Engagement Score - Azure Event Score - Azure Usage Score - Azure Marketplace Count - Azure Marketplace Review Count - Azure Marketplace Purchase Count **GCP Signals** - GCP Engagement Score - GCP Marketplace Count - GCP Marketplace Review Count - GCP Marketplace Purchase Count ## Example Configuration To enrich Opportunities in the Prospecting stage with AWS engagement data: 1. **CRM Record Type**: Opportunity 2. **Field Mappings**: - `AWS Engagement Score` → `aws_engagement_score` 3. **SOQL Query**: `SELECT Id FROM Opportunity WHERE StageName = 'Prospecting'` ## How Enrichment Works ### Sync Schedule Fours runs a scheduled enrichment sync **every 2 hours**. During each sync, Fours automatically processes all configured enrichment rules for your organization. ### Enrichment Process Each sync goes through the following steps: 1. **Query your Salesforce org** using the configured SOQL query to identify records that need enrichment. 2. **Look up intelligence data** for each matching record based on the company's website domain. 3. **Update the mapped fields** in Salesforce with the latest intelligence values. ### Update Mechanism Fours uses a smart two-step approach to ensure efficient and complete data coverage: - **Step 1 — Enrich new records**: Every sync prioritizes records that have **not been enriched yet** (where the mapped fields are still empty). This ensures newly added or previously missed records receive intelligence data first. - **Step 2 — Refresh existing records**: Once all new records have been enriched, Fours begins a **refresh cycle** — rotating through previously enriched records in batches to keep data up to date. This rotation continues across multiple syncs until all records have been refreshed, then a new cycle begins. The **Refresh Existing** setting controls how the refresh cycle behaves: | Setting | Behavior | |---------|----------| | **Never** | Only enrich records that have not been enriched before. Previously enriched records are never updated. | | **Immediately** | Continuously rotate through all records, refreshing data without delay between cycles. | | **Every N days** | Wait N days after completing a full refresh cycle before starting the next one (default: 30 days). | ### Records Per Sync Each sync processes up to a configurable maximum number of records. For Salesforce, the default is **10,000** and can be increased up to **50,000**. The minimum configurable value is **1,000**. If your query matches more records than the configured limit, the remaining records are handled automatically: - **New records (Step 1)**: Unenriched records will be picked up in the next sync since they still have empty fields — no progress tracking is needed. - **Refresh cycle (Step 2)**: Fours tracks its cursor position across syncs to rotate through all records. For example, with 100,000 records and a limit of 50,000 per sync, the refresh cycle completes in 2 runs. Once a full cycle finishes, the next one starts based on your **Refresh Existing** setting. ### Tracking Enrichment Progress To monitor the status of your enrichment sync: 1. Go to the enrichment configuration for your record type 2. Expand **Advanced Configuration** 3. Click **Check Progress** The progress panel shows: | Field | Description | |-------|-------------| | **Status** | Current state — *Active* (only enriching new records, refresh disabled), *Not Started*, *In Progress*, or *Waiting* (cycle completed, waiting for next refresh interval) | | **Cycle Progress** | Percentage of records processed in the current refresh cycle | | **Records Processed** | Number of records processed out of total matching records | | **Last Run** | When the last sync ran and how many records it processed | | **Estimated Runs Remaining** | Approximate number of syncs needed to complete the current cycle | ### Disabling Enrichment To stop enrichment for a specific record type, toggle it **off** in the enrichment configuration. This removes the enrichment rule, and no further syncs will process that record type. To temporarily pause enrichment without removing the configuration, set **Refresh Existing** to **Never** — this will only enrich new records with empty fields and skip all previously enriched records. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-permission-sets/ # Permission Sets Fours uses Salesforce Permission Sets to strictly control user access. These permission sets determine which Fours Tabs are visible to a user and which Action Buttons (e.g., Create Private Offer) appear on their record pages. For configurations related to the external Fours Integration platform (such as API credentials or mapping rules), please refer to [the Fours Integration Setup Guide](/integrations/salesforce/). :::note **Admin Privileges:** Fours Permission Sets **do not restrict** users with System Administrator privileges. Admins inherently possess full Read/Write access to all Fours features and Cloud Partners, regardless of the specific permission set assigned to them. ::: --- ## How to Access Permission Sets To view or assign these permissions in your Salesforce environment: 1. Click the **Gear Icon (⚙️)** in the top-right corner of the screen and select Setup. 1. In the **Quick Find** box on the left sidebar, type `Permission Sets`. 1. Select **Permission Sets** from the results to view the list of available Fours permissions. 1. All Fours-related permission sets begin with the prefix `Suger`. Assign the appropriate set based on the user's role in your sales cycle. Fours provides granular Permission Sets to control access based on Role (Admin vs. User), Module (Marketplace vs. Co-sell), and Cloud Partner (AWS, Azure, GCP). Use the tables below to assign the correct permissions to your users. --- ## Core Roles & Admin Permissions These permission sets provide high-level access control. | Permission Set Name | Description & Capabilities | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Suger Approval Offer | Grants permission to **Approve** or **Reject** Marketplace **Offers** (via the `Approve_Offer` custom permission). The approval process can be enabled via Salesforce integration settings in the [Fours Console](https://console.suger.io). | | Suger Approval Cosell | Grants permission to **Approve** or **Reject** **Co-sell Referrals** (via the `Approve_Cosell` custom permission). Assign separately from Suger Approval Offer if a user should be able to approve referrals but not offers (or vice versa). | | Suger Integrator | **Integration User Only.** Grants full Read/Write access to all Fours objects, including the Settings page and configurations. Do not assign this to human users. | | Suger Integrator (Salesforce Integration License) | **API User Only.** Grants full system access specifically for users holding the Salesforce Integration License. Do not assign this to standard human users. | | Suger User | **Standard User.** Grants full Read/Write access to all Fours objects (Offers, Referrals, etc.) across all clouds. **Excludes** access to the Settings page. | | Suger User - Read Only | **Global View-Only.** Grants view-only access to all Fours data. Users cannot create or edit records. | | Suger User - Cosell | Grants Read/Write access specifically to **Co-sell Referrals** for _all_ cloud partners. | | Suger User - Marketplace | Grants Read/Write access to **Offers, Entitlements, Products, Buyers, and Companies** for all cloud partners (Excludes access to Co-sell Referrals). | --- ## Co-Sell Cloud-Specific Permissions Use these permissions to restrict a user's **Referral** access to a specific Cloud Provider. These permissions also affect the user's visibility into CoSell Insights, such as Engagement Score, Possible Sales Reps, and related metrics. These permissions **do not** grant access to Offers, Entitlements, Products, or Companies(Buyers). | Permission Set Name | Description | | -------------------------------- | ----------------------------------------------------------------- | | Suger Cosell (Read Only) | View-only access to Co-sell Referrals for **all** cloud partners. | | Suger Cosell - AWS | Read/Write access to Co-sell Referrals for **AWS** only. | | Suger Cosell - AWS (Read Only) | View-only access to Co-sell Referrals for **AWS** only. | | Suger Cosell - Azure | Read/Write access to Co-sell Referrals for **Azure** only. | | Suger Cosell - Azure (Read Only) | View-only access to Co-sell Referrals for **Azure** only. | | Suger Cosell - GCP | Read/Write access to Co-sell Referrals for **GCP** only. | | Suger Cosell - GCP (Read Only) | View-only access to Co-sell Referrals for **GCP** only. | --- ## Marketplace Cloud-Specific Permissions Use these permissions to restrict a user's **Offer & Entitlement** access to a specific Cloud Provider. These permissions **exclude** access to Referrals. :::note Assigning any of the permission sets below automatically grants access to shared Marketplace objects, including **Buyers**, **Companies**, and **Products**. The "Cloud-Specific" restriction only applies to Offers and Entitlements. ::: | Permission Set Name | Description | | ------------------------------------- | ----------------------------------------------------------------------- | | Suger Marketplace (Read Only) | View-only access to Offers and Entitlements for **all** cloud partners. | | Suger Marketplace - AWS | Read/Write access to **AWS** Offers and Entitlements. | | Suger Marketplace - AWS (Read Only) | View-only access to **AWS** Offers and Entitlements. | | Suger Marketplace - Azure | Read/Write access to **Azure** Offers and Entitlements. | | Suger Marketplace - Azure (Read Only) | View-only access to **Azure** Offers and Entitlements. | | Suger Marketplace - GCP | Read/Write access to **GCP** Offers and Entitlements. | | Suger Marketplace - GCP (Read Only) | View-only access to **GCP** Offers and Entitlements. | | Suger Marketplace - SNOWFLAKE | Read/Write access to **Snowflake** Offers and Entitlements. | | Suger Marketplace - SNOWFLAKE (Read Only) | View-only access to **Snowflake** Offers and Entitlements. | | Suger Marketplace - ORACLE | Read/Write access to **Oracle** Offers and Entitlements. | | Suger Marketplace - ORACLE (Read Only) | View-only access to **Oracle** Offers and Entitlements. | --- ## Lead Access [AWS co-sell leads](/salesforce-app/salesforce-app-leads/) are governed by the **AWS referral** permissions, not by a set of their own: reading the Leads tabs needs AWS referral read, and accepting, rejecting, qualifying, converting, or linking a lead needs AWS referral write. | Permission Set | Lead records | Leads tabs | | -------------- | ------------ | ---------- | | Suger Integrator, Suger Integrator (Salesforce Integration License) | Read/Write | Visible | | Suger User | Read/Write | Visible | | Suger User - Cosell | Read/Write | Visible | | Suger Cosell - AWS | Read/Write | Visible | | Suger User - Read Only, Suger Cosell (Read Only), Suger Cosell - AWS (Read Only) | View-only | Visible | | Suger Cosell - Azure, Suger Cosell - GCP (and their Read Only variants) | **No access** | Visible | :::warning The Azure and GCP co-sell sets make the **Leads V2 (Suger)** and **Lead Detail (Suger)** tabs visible **without** granting access to the Lead object, so a user holding only one of them opens the tab and sees nothing. Pair them with an AWS co-sell set, or assign **Suger User**, if that person is meant to work leads. Marketplace-only sets carry neither the object nor the tabs. ::: --- ## Funding Permissions Use these permissions to grant access to **AWS Funding** features (e.g., Fours Funding Request objects, funding approval workflows). These are typically assigned in addition to a marketplace permission set when a user needs to manage funding alongside their normal Offer/Entitlement work. | Permission Set Name | Description | | -------------------------- | ------------------------------------------------------------------------------------------ | | Suger Funding | Read/Write access to AWS Funding operations. | | Suger Funding (Read Only) | View-only access to AWS Funding operations. | Both sets make the **Funding V2 (Suger)** tab and the Funding object's own tab visible. Funding records are searchable in Salesforce global search — see [How Funding records open](/salesforce-app/salesforce-app-settings/#how-funding-records-open). --- ## Add-on Permissions These permission sets do not grant a baseline level of access on their own — they layer specific feature capabilities on top of a primary permission set. | Permission Set Name | Description | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Suger User Finance Operation | Grants access to **Finance Operation** features (Cancel / Billing Adjustment) on the Suger Entitlement record page via the `Finance_Operation` custom permission. Finance Operation access also requires AWS marketplace write access (the `Write_AWS_Offer` custom permission), so this add-on **must be combined** with a base permission set that grants it — `Suger User`, `Suger User - Marketplace`, or `Suger User - Marketplace - AWS`. | :::note **AWS EMEA SARL invoices cannot be adjusted through Fours.** AWS requires a KYC-verified user with MFA to adjust an invoice issued by its EMEA entity, and Fours submits adjustments through an integration role, which can never be one. In the **Billing Adjustment** modal those invoice rows keep a disabled checkbox and read *"Issued by AWS EMEA SARL — AWS requires a KYC-verified user to adjust it."*, followed by a **Must be adjusted in AWS ↗** link. When every invoice in the billing term is affected, the same note appears above the table with a **Complete adjustment in AWS Partner Central ↗** link. Both links open the AWS Marketplace agreements page, where you sign in as your own KYC-verified AWS user and make the adjustment. If AWS refuses an adjustment for this reason after it was submitted, its row in the entitlement's **Adjustment Requests** table carries the same **Must be adjusted in AWS ↗** link. This is an AWS restriction, not a permission you can grant. ::: --- ## Custom Permissions For detailed information about the custom permissions included in each permission set, see [Custom Permissions](/salesforce-app/salesforce-app-custom-permissions/). --- Source: https://doc.fours.com/salesforce-app/salesforce-app-page-components/ # Page Components Fours ships a set of **Lightning components** you can drop onto record, app, and home pages with the **Lightning App Builder** — no code required. They surface Fours' co-sell and marketplace functionality directly inside your Salesforce record pages. These are separate from [Quick Actions](/salesforce-app/salesforce-app-quick-actions/) (the action buttons in the highlights panel) — the components below are full **panels and cards** you place in the body of a page. --- ## Overview There are two kinds of things you can add to a Salesforce record page, and they appear in different places: | What | Where it appears | What it does | | ---- | ---------------- | ------------ | | **Page components** (widgets and cards) | The body of the record page, below the highlights panel | Show Fours offers, referrals, entitlements, and insights linked to the record, and let users act from there | | **[Quick Actions](/salesforce-app/salesforce-app-quick-actions/)** (action buttons) | The highlights panel at the very top of the record page | One-click buttons like _New Offer via Suger_ and _Co-Sell via Suger_ that open a focused flow immediately | You can add one or both. Most teams add both — the widget for visibility and the buttons for quick access. This page covers the **page components**; see [Quick Actions](/salesforce-app/salesforce-app-quick-actions/) for the buttons. ### Prerequisites - The Fours App must be installed and connected to Salesforce. See the [Salesforce integration setup guide](/integrations/salesforce/). - Your team must have Fours permission sets assigned. See [Permission Sets](/salesforce-app/salesforce-app-permission-sets/). Permission sets control which components and buttons each person actually sees — adding a component to the page without assigning permission sets means those users will see nothing. - You need **Salesforce Administrator access** to edit page layouts and record pages. --- ## How to add a component 1. Open the record (or app/home) page you want to edit and choose **Setup (⚙️) → Edit Page** to open the Lightning App Builder. 2. In the **Components** list on the left, scroll to the **Custom** (managed) section and find the Fours component by name (e.g. _Suger Opportunity Quick Panel_). 3. Drag it onto the page where you want it to appear. 4. **Save**, then **Activate** the page (as org default, or by app/profile, as needed). :::note Each component only appears in the App Builder on the page types it supports, and some are **locked to specific objects** (noted below) — they won't show up when you're editing another object's page. ::: :::tip **Don't forget to click Activate.** Saving the page in the Lightning App Builder does not publish it to users — you must also activate it. You can activate as **Org Default** for everyone, or by app or profile for more control. ::: --- ## Opportunity components These surface Fours on the **Opportunity** record page — the main workspace for a sales rep. | Component | What it does | | --------- | ------------ | | **Suger Opportunity Quick Panel** | The primary, all-in-one Fours widget — surfaces co-sell **and** marketplace together in a single panel. The Marketplace tab lists the opportunity's offers and entitlements; the Co-Sell tab also carries a **Leads** section for the opportunity's Account, where you can [enrich that Account into an AWS lead](/salesforce-app/salesforce-app-leads/#enrich-an-account-into-an-aws-lead). Use this when you want one component that does everything. | | **Suger Cosell Actions Quick Panel** | The co-sell **actions** — share the opportunity as a referral with AWS, Azure, or GCP and run co-sell operations. _(Locked to Opportunity.)_ | | **Suger Cosell Referrals Quick Panel** | The co-sell **list** — the referrals created from or linked to this opportunity. _(Locked to Opportunity.)_ | | **Suger Marketplace Actions Quick Panel** | The marketplace **actions** — create private offers and related operations. _(Locked to Opportunity.)_ | | **Suger Marketplace Offers Quick Panel** | The marketplace **list** — the offers linked to this opportunity. _(Locked to Opportunity.)_ | | **Suger Cosell Leads Quick Panel** | The [AWS co-sell leads](/salesforce-app/salesforce-app-leads/) attached to this opportunity. _(Locked to Opportunity.)_ | | **Suger Account Insights** | The customer's full picture — a **Suger Predicted Engagement Score** line on both page types, plus a **Marketplace / Co-Sell / Funding / Contacts** widget when placed on an Account page. _(Available on Account and Opportunity pages — see [Suger Account Insights](#suger-account-insights) below.)_ | :::tip The Quick Panels come as an **Actions + List** pair for each area (Co-Sell and Marketplace), so you can place them independently — for example, the actions panel near the top of the page and the list further down. Prefer the **Suger Opportunity Quick Panel** if you'd rather have a single combined widget instead. ::: ### Associated Contacts on an opportunity The **Associated Contacts** section of the Opportunity Quick Panel is **scoped to the clouds this opportunity was actually shared with**: once the opportunity carries at least one cloud referral, the section shows partner contacts for those clouds only, instead of every cloud your org has integrated. Two deliberate exceptions keep the scope from hiding contacts you are entitled to: - **No visible cloud referral, no filter.** If the opportunity has no cloud referrals — a PRM-only deal, for example — or the referral list could not be read, the scope is treated as unknown and every cloud is shown. - **A cloud you cannot read stays in scope.** Not seeing a cloud's referrals is not evidence there are none, so a cloud whose referrals your permission set hides is never filtered out. A user with a single-cloud read grant therefore always sees the section unfiltered. --- ## Suger Account Insights **Suger Account Insights** is the one component that works on both **Account** and **Opportunity** pages, and it renders differently on each. On an Opportunity page it is a compact insight line; on an Account page it is a full widget covering the customer's marketplace activity, co-sell referrals, funding requests, and the partner contacts who cover them. ### On both Account and Opportunity pages The component opens with a **Suger Predicted Engagement Score** line for the customer: Fours' own prediction of how likely this customer is to buy through AWS, Azure, or GCP, from marketplace activity and third-party signals. It is not the score a cloud partner gives an opportunity — that one appears on the referral as **Engagement Score** — and it is not stored on the Referral record, so it does not appear in reports built on that object. The heading's tooltip says the same. The same line also heads the **Suger Opportunity Quick Panel** and the **Suger Cosell Actions Quick Panel**. See [Co-sell Insights](/cosell/co-sell-insights/) for how the two scores differ. ### On Account pages only Below the score, an Account page adds a tab switcher. Marketplace is always there; the rest appear when your org has the feature configured and the user has access to it: | Tab | What it shows | When it appears | | --- | ------------- | --------------- | | **Marketplace** | **Active Offers** — the account's live offers — followed by **Active Entitlements**, the contracts currently running for this account. | Always. | | **Co-Sell** | **Referrals** across the account's opportunities, plus any linked to the account directly. Read-only — referrals are created from the Opportunity page, which carries the context they need. Below them, **Leads** — the account's AWS co-sell leads, with **Create & enrich** / **Re-enrich** to [send the account to AWS for lead enrichment](/salesforce-app/salesforce-app-leads/#enrich-an-account-into-an-aws-lead) once your Fours admin has saved a Salesforce lead-enrichment mapping. | Co-sell is configured for your org and the user can read referrals for at least one cloud. The **Leads** section itself needs AWS referral read, and is hidden when the account has no leads and no mapping is saved. | | **Funding** | **Funding Requests** — AWS funding reached two ways: linked to one of the account's opportunities, or found through the account's AWS co-sell referrals. Funding attaches to an AWS co-sell opportunity, never to the account itself, so a referral linked straight to the account still surfaces its funding even with no Salesforce opportunity involved. Read-only. | The user has funding read or write access. | | **Contacts** | **Buyer Contacts** — the account's own people, taken from its offers (see [Buyer Contacts](#buyer-contacts) below). When co-sell is configured for your org, also **Associated Contacts** — the partner contacts linked to this account. | The user can read AWS, Azure, or GCP referrals **or offers**. Co-sell is not required. | :::note The Funding tab scans a recent page of referrals rather than every one, so on an account with a lot of co-sell history the list can be partial. When that limit is reached the tab says so above the rows. ::: Each of these tabs that has rows carries its own **List / Board** toggle and its own **search box**, and remembers its List/Board choice independently — see **List vs. Board** below. **Finding an offer.** Once there is at least one active offer, a **search box** appears above the list. It filters the offers already loaded in the widget by **offer name**, **offer ID**, **billing account ID**, or **product name** — it does not re-query the server, so results come back as you type. **List vs. Board.** A **List / Board** toggle switches between the row view and the card view. **List is the default** wherever the component has at least **600px** of width — it fits far more offers on screen and lines their status and acceptance up in comparable columns — and your last choice is remembered, so a user who switched to Board lands back on Board. The toggle — together with the search box — appears on **each tab that has rows** (Marketplace, Co-Sell, Funding, and Contacts), and **each tab keeps its own List / Board choice**: switching Marketplace to Board leaves Co-Sell on List until you switch it too. Below 600px there is no room for the list's seven columns, so the toggle is hidden and **Board** is used regardless of the stored preference. **Sorting the list.** In **List** view the **Created** and **Expires** column headers are buttons. The list opens sorted by **Created, newest first**; clicking a header sorts by it, and clicking the same header again reverses the direction. The header shows which is active — `⇅` while idle, an up or down arrow once it is the sort column. Sorting is a property of the List view only: **Board** groups cards by status and is not sorted. Rows carry the identifiers you need to reconcile a record against the marketplace: | Row field | Appears on | What it is | | --------- | ---------- | ---------- | | **Partner ID** | Offers and entitlements | The seller marketplace integration account that owns the offer or entitlement — for AWS, the 12-digit seller AWS account ID. | | **Billing account** | Offers and entitlements | The buyer's account on the cloud side. Named the same way on every marketplace — see below. | | **Contract Term** | Offers | The term the offer runs for, normalized from however that cloud states it. | | **Reseller ID** | Offers, CPPO only | The reseller on a channel deal — shown only when the offer is a [reseller authorization / CPPO](/salesforce-app/salesforce-app-cppo/), inbound or outbound. | Offer rows also carry the offer's external ID, product name, create and expire dates, and — once accepted — the acceptance date. Entitlement rows carry the external ID, product name, status, type, and start and end dates. Identifier values can be copied straight from the row. **The buyer block has one name on every cloud.** An offer card lists the accounts the offer was made out to under **Billing account** / **Billing accounts** — on AWS, on GCP, on Azure, and on any marketplace not named there (Snowflake, Oracle, Alibaba Cloud) as well. The widget used to mirror each cloud's own word for it — "buyer account" on AWS, "billing account" on GCP, "buyer ID" on Azure — which taught sellers three names for one column. A cross-cloud widget uses the cross-cloud name. That name is now used in four places at once: the **Board** view's card block, the **List** view's column header on both Active Offers and Active Entitlements, the offer search box, and the expanded entitlement card. Each buyer row carries its own status badge, derived from the entitlement behind it rather than from the offer: | Badge | What it means | | ----- | ------------- | | **Accepted** | The buyer accepted; an agreement exists (also shown while the agreement is scheduled to start). | | **Pending acceptance** | The buyer has produced no entitlement yet. | | **Suspended** | The agreement is suspended. | | **Cancellation pending** | Cancellation has been requested and is not yet complete. | | **Cancelled** | The agreement was cancelled. | | **Replaced**, **Renewed**, **Superseded** | The marketplace cancelled the agreement because a newer one took over. The three are kept distinct because a renewal is not a replacement. | | **Acceptance unknown** | Fours could not read all of this customer's entitlements, so a buyer who has accepted may still read as unknown. This is now rare: it means the Fours API could not be reached, a buyer lookup failed, or the account holds more entitlements than Fours will page through in one load. A large account on its own no longer causes it. Refresh the page; if it persists, contact Fours support. | The **card's** own status badge additionally shows **Partially accepted** when some buyer accounts on a multi-buyer offer have accepted and the rest are still pending. Hovering a card status explains it in plain language. **What the count counts.** `M` is the number of accounts the **offer was made out to** — not the number of agreements that exist. On AWS a targeted account can *distribute grants* to other accounts that the offer never named; each of those produces its own agreement. Those agreements appear in **Active Entitlements**, but they are deliberately **not** counted as acceptances of the offer, because the accounts holding them were never targeted by it. This is why an offer can read `1 of 1 accepted` while the AWS console shows several active agreements for the same customer. A multi-buyer offer also carries an acceptance count beside its status, written as **`N of M`** — for example `1 of 2`. When entitlements could not all be read, the count reads **`at least N of M`**, because the true number can only be higher than the rows Fours could see. On an **offer set** the same shape counts member offers rather than buyers: `1 of 2 accepted` means one of the two offers in the set is fully accepted. **Acceptance Date on an offer.** An offer made out to more than one buyer shows a dash (`—`) here rather than a date, and the tooltip points you to the entitlements below. This is deliberate: each buyer accepts separately, so there is no single date that belongs to the offer — the per-buyer rows carry each real one. An offer with a single buyer shows that buyer's acceptance date as normal. A dash also appears when no acceptance date was recorded on the offer at all; the two cases have different tooltips. **End Date on an entitlement.** An agreement with no scheduled end reads **No end date**. That is a statement about the contract, not a gap in Fours' data — an entitlement whose end date has not been synced shows no End Date row at all. A marketplace signals "no scheduled end" with a far-future date rather than an empty one, so a subscription agreement carries an end date in the year **9999**. Every Fours surface resolves that to **No end date** instead of printing it: the account widget, the **offer** page, the **entitlement detail** page, and the **entitlement list**. If you ever see a date in 9999 on a Salesforce record, it came from a field Fours did not render — a formula or report built directly on the raw value — not from the app. **Actions on an offer card.** Two buttons sit at the bottom of the card while the offer still needs someone to accept it: | Action | What it does | | ------ | ------------ | | **Send reminder to contacts** | Opens the reminder prompt, which lists the offer's notification contacts — plus **Suggestions** from the account when contact routing is on — and mails a reminder to the people you tick. If you hold the **Modify Offer Contacts** custom permission or write access to that cloud's offers, **Add contact** inside the prompt attaches another person first — offered whether the list is empty or already populated. | | **Copy private offer URL** | Copies the buyer-facing acceptance link. Shown only once the marketplace has returned a URL. | Both actions — and the whole action row — **disappear once every targeted buyer has accepted**: the acceptance link is spent at that point, and offering it would invite a seller to chase a customer who has already signed. **Who the reminder goes to.** The prompt lists the offer's own notification contacts, already ticked. When contact routing is on (see [Buyer Contacts](#buyer-contacts)) and the offer's product carries a product line, a **Suggestions** list follows: people on this account filed under that product line who are not on the offer yet, each with a product-line badge, unticked. Tick a suggestion and Fours adds that person to the offer's notification contacts before sending, so a reminder can reach routed contacts even when the offer has none of its own. The button counts the emails it is about to send — **Send 1 reminder**, **Send 3 reminders** — and stays disabled until someone is ticked. When the offer has no contacts and nobody is suggested, the prompt goes straight to **Add contact** if you are allowed to add one. ```d2 direction: right own: "Offer's notification contacts\n(ticked)" suggested: "Suggestions: account people\nunder the offer's product line\n(unticked)" pick: "You tick who\nshould be reminded" attach: "Ticked suggestions are\nadded to the offer" send: "Reminder emailed to\neveryone ticked" own -> pick suggested -> pick pick -> attach -> send ``` **GCP universal PAYG discount.** When a GCP offer was priced with one discount across all usage rather than per-dimension rates, the card shows a banner above the buyer block reading the discount — for example **20% off all usage** — captioned *Universal PAYG discount*. ### Buyer Contacts The **Contacts** tab opens with **Buyer Contacts**: the account's own people, taken from the offers on this account. When the Account has a **Website**, only addresses at that domain or one of its subdomains are listed, so your own reps and anyone else named on an offer are left out. With no Website, everyone the offers name is listed. Partner and seller reps are never included. ```d2 direction: right offers: "People named on\nthis account's offers" domain: "People at the Account's domain\nfiled under one of its\nproduct lines\n(contact routing on only)" filter: "Keep the Account's\nown email domain" routing: "Contact routing on?" { shape: diamond } rows: "One row per product line\nyour products carry,\nplus Unassigned" flat: "One ungrouped list" offers -> filter domain -> filter filter -> routing routing -> rows: "yes" routing -> flat: "no" ``` How the list is organized depends on **Contact routing**, a switch under **Product Tagging** in the Fours Console — open **Offer**, then the **Settings** tab and its **Products** sub-tab: | Contact routing | What the panel shows | | --------------- | -------------------- | | **On** | One row for **every product line your org's products carry**, in alphabetical order, each with a count — including lines nobody on this account is filed under yet, so there is always a row to file the account's first contact under. Expand a row to see its people. People with no product line are grouped under **Unassigned**. | | **Off** | The account's people as one ungrouped list. | The rows come from your products, not from this account's offers, so an account with no Fours offers still shows every line. The domain filter still applies to the people inside each row: a row whose people are all at other domains stays on the panel, empty. A search box (*Search contacts (name, email, tag)*) filters the list as you type — it also matches a product line's own name, so you can reach an empty line by typing it — and **Expand all** / **Collapse all** opens or closes every row at once. **File a contact under a product line.** With contact routing on, each product-line row has an **Add contact** button. It is disabled, with the tooltip *Set this account's website to enable*, until the Account has a **Website** — filing someone needs a domain to show them against. 1. Click **Add contact** on the row. 2. Pick the person in the contact picker — a Salesforce contact or user, an existing Fours contact, or a new one. The picker opens on **Create Offer Contact**, for someone new. 3. Fours files them under that product line and reloads the panel. The confirmation tells you where they landed: - *Contact added to {product line}.* — they now appear in that row. - *Filed under {product line}, but not shown here.* — the filing worked, but *This panel lists the people on this account's offers, and those at its email domain. Add them to one of its offers to see them here.* A trash icon (**Remove from this product line**) appears only on people filed by hand. Removing one confirms with *Contact removed from {product line}.* People placed by contact routing follow their offer's product, so they have no trash icon. Adding and removing need the **Modify Offer Contacts** custom permission — **Create Offer** does not grant it here. See [Custom Permissions](/salesforce-app/salesforce-app-custom-permissions/). If a load, add, or remove fails, the message ends *if it keeps failing, contact Suger*. The panel shows a spinner until the account's offers have loaded, then *No contacts on this account yet* only when there is nobody to list **and** no product-line row to show — with contact routing on and tagged products, the rows are always there. :::note **The tab switcher only renders on an Account page.** On an **Opportunity** page there is no switcher at all — just the Suger Predicted Engagement Score line. The switcher is also dropped when Marketplace is the only tab you qualify for. With nothing to switch to, the Marketplace content simply renders on its own rather than behind a one-button switcher. Inside the Contacts tab, **Associated Contacts** appears when your org has co-sell configured, and it needs the Account to have a **Website** — Fours matches partner contacts to an account by its company domain. An account with an empty Website field has nothing to match on, so the tab shows **"No associated contacts to display"**, noting that the account has no Website set. Fill in the Website and reload the page. **Buyer Contacts** works without a Website: it then lists everyone the account's offers name. ::: --- ## Object detail cards Read-only **detail views** of a Fours record, shown on that object's record page. They already ship on Fours' packaged record pages; add them here only if you're building a custom page for one of these objects. To add one, follow the same steps as adding a widget — open the object's record page in the Lightning App Builder, find the card in the **Custom** components section, and drag it onto the canvas. | Component | Record page | | --------- | ----------- | | **Suger Buyer Detail Card** | Buyer | | **Suger Entitlement Detail Card** | Entitlement | | **Suger Offer Detail Card** | Offer | | **Suger Product Detail Card** | Product | | **Suger Referral Detail Card** | Referral | ### Suger Entitlement Detail Card **Amendment banner.** When the offer currently linked to an entitlement is a replacement (amendment) offer, an info banner sits above the field grid reading: > This entitlement originated from an amendment. It is now storing the information for offer *{offer name}*. Fours relinks the entitlement onto the accepted replacement offer, so the banner is there to explain why the entitlement's offer details are no longer the ones the buyer originally accepted. **Organization.** GCP private offers name a customer organization, so entitlements and offers that came from one carry an extra **Organization** tile at the top of the card. No other marketplace puts a customer organization on its offer, so the tile is not shown for them at all — it is **omitted rather than rendered "N/A"**, which is also how the sub-status tile behaves. An empty header tile reads as missing data; an absent one reads as "this cloud has no such field," which is the true statement. **GCP dates in Pacific time.** A GCP entitlement's **Start Date** and **End Date** show as a Pacific date and time with the **PST** or **PDT** label, matching GCP's Producer Portal. The Suger Entitlement page shows them the same way. Entitlements on other marketplaces keep showing the date alone. **Linking an opportunity to a public-offer entitlement.** Entitlements that came from a **public** offer — a `DEFAULT` or `FREE_TRIAL` listing offer — can be linked to a Salesforce Opportunity from this card. A public offer is buyer-agnostic and can never carry a link to one specific opportunity, so the link is stored on the **individual entitlement** rather than on the shared offer. For private-offer entitlements the link continues to live on the offer, which then propagates it to every entitlement under that offer. --- ## Troubleshooting | Issue | Possible cause | Resolution | | ----- | -------------- | ---------- | | Fours component is not visible in the **Components** panel | The Fours package isn't installed, or the page type doesn't support the component | Confirm the Fours App is installed. Fours components only appear on supported page types — opportunity-specific components won't show when editing Account or Contact pages. | | Component is on the page but shows a **"Feature Disabled"** message | The feature has been disabled in Fours App Settings | In the Suger app in Salesforce, go to **Settings → Tabs Control** and turn off the toggle for the relevant feature. | | Buttons appear on the page but users can't see them | The user doesn't have the correct Fours permission set assigned | In **Setup → Permission Sets**, assign the appropriate [Fours permission set](/salesforce-app/salesforce-app-permission-sets/). | | Page changes aren't showing for users after saving | The page was saved but not activated | Return to the Lightning App Builder and click **Activate**. | --- ## Frequently asked questions **Do I need to add the widget and the quick action buttons, or just one?** You can add either or both — they serve different purposes. The widget shows a full view of offers and referrals linked to the record. The [quick action buttons](/salesforce-app/salesforce-app-quick-actions/) give reps a shortcut to create something new without scrolling to the widget first. Most teams use both. **Can I add the Fours widget to Account or Contact pages too?** The opportunity-specific panels (like **Suger Opportunity Quick Panel**) are locked to the Opportunity object and won't appear on other page types. The **Suger Account Insights** component is available on both Account and Opportunity pages — and the Account page gets the fuller version: not just the Suger Predicted Engagement Score, but the **Marketplace / Co-Sell / Funding / Contacts** switcher, showing only the tabs your org has configured and the user has access to. See [Suger Account Insights](#suger-account-insights). There is no Fours component for the Contact object. **I added Suger Account Insights to my Account page, but a tab is missing.** Each optional tab has its own requirement. **Co-Sell** needs a co-sell integration plus referral read access, so marketplace-only access is not enough. **Contacts** needs read access to AWS, Azure, or GCP referrals **or offers**, and does not need co-sell. **Funding** needs funding read or write access. When Marketplace is the only tab you qualify for, the tab switcher is dropped entirely and the Marketplace content renders on its own. If the Contacts tab is there but **Associated Contacts** is missing or empty, check that your org has co-sell configured and that the Account record has a **Website** — Fours matches partner contacts by the account's company domain. See [Suger Account Insights](#suger-account-insights). **Can different teams see different widgets on the same opportunity page?** Yes — you can activate different page layouts by app or profile in the Lightning App Builder. For example, your marketplace team can have a page showing the offers widget, while your co-sell team sees the referrals widget. **When would I need to add an object detail card manually?** Only when you're building a custom record page for a Fours object like Offer or Referral. If you're using Fours' default packaged record pages, the detail cards are already included and don't need to be added manually. --- ## Related - [Quick Actions](/salesforce-app/salesforce-app-quick-actions/) — the Fours action buttons (Co-Sell, Create Offer, etc.) for the highlights panel. - [Permission Sets](/salesforce-app/salesforce-app-permission-sets/) — control which users see Fours tabs, components, and actions. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-settings/ # App Settings This guide covers configuration options available within the Fours App settings and Salesforce setup. --- ## API Connectivity To connect the Fours Salesforce App with the Fours platform, you need to configure API credentials and integration settings. This includes setting up authentication, mapping rules, and [sync preferences](/integrations/salesforce/#choose-what-backfills-to-salesforce). For detailed instructions on configuring API connectivity, see the [Salesforce Integration Setup Guide](/integrations/salesforce/#configuration). ### OAuth credentials are required for AI notes **Generate AI Notes** in the Azure co-sell share wizard calls Fours' AI service, which accepts **Bearer tokens only**. An org still authenticating with an API key alone gets a `401` back and the button fails with: > AI note generation requires OAuth. Add the Suger OAuth Client ID and Client Secret in Suger Settings, then try again. Add the **Suger OAuth Client ID** and **Client Secret** in Suger Settings to enable it. Everything else in the app continues to work on the API key. :::note The button is also gated on **Azure referral write** access, the same permission its sibling controls in that wizard require. ::: --- ## Managing Tab Visibility The Fours App includes both V1 and V2 tabs. The key differences are: - **V1 tabs** use Salesforce Lightning Record Tables that read from local Salesforce objects. Data may be delayed due to sync intervals between Fours and Salesforce. - **V2 tabs** read data directly from the Fours platform via API, providing real-time, up-to-date information. To streamline the user experience and reduce clutter, Admins can hide unused or legacy tabs using one of the following methods. ### Method 1: Hide Tabs via App Manager This method removes tabs from the default navigation bar for all users accessing the Fours App. **How to Configure:** 1. Click the **Gear Icon (⚙️) > Setup**. 1. In the Quick Find box, type `App Manager`. 1. Locate the `Suger` in the list. Click the **dropdown arrow (🔽)** on the right and select **Edit**. 1. Select **Navigation Items** from the left-hand menu. 1. Select the tabs you wish to hide from the **Selected Items** list (right side) and use the **Remove Arrow (⬅)** to move them to the **Available Items** list (left side). 1. Click **Save**. :::warning This method only removes tabs from the default navigation bar. It does not strictly remove permission. Users can still access these tabs via the App Launcher or global search if they look for them explicitly. ::: :::note If you encounter a lock icon next to an item in the list, it indicates you do not have the necessary permissions to modify this setting. Please consult your organization's Salesforce System Administrator for assistance. ::: ### Method 2: Disable V2 Access via Fours Settings Unlike Method 1, which removes the tab from the navigation bar, this method **does not hide the tab**. Instead, it functionally **disables** the page content. If a user clicks on a disabled tab, the page will load, but they will see a "Feature Disabled" message and cannot interact with any data. **How to Configure:** 1. Open the Salesforce Suger App and navigate to the **Suger** tab. 1. In settings menu, scroll down to the **Tabs Control** section. 1. Locate the specific V2 page you wish to restrict. 1. Turn ON the toggle to disable the feature. --- ## Adding the Referrals Tab To streamline your referral workflows and ensure quick access to key information, we recommend adding the **Referrals tab** to your Salesforce navigation bar. This lets you easily track both **inbound referrals from AWS** and **outbound referrals submitted by your team**. **How to Configure:** 1. On the **top-right corner** of your Salesforce screen, click the **pencil icon** (Customize My Navigation) to open the Navigation Editor. ![Open the Navigation Editor from the pencil icon](images/how-to-configure-your-salesforce-for-ref-1.gif) 1. In the editor, click **Add More Items**, then go to the **All** section to see a list of available navigation items. ![Add more navigation items from the All section](images/how-to-configure-your-salesforce-for-ref-2.gif) 1. In the search bar, type `Suger`. Find and select **Referrals V2 (Suger)**, then click **Add 1 Navigation Item**. We suggest placing the **Referrals** tab directly below **Opportunities**, since they are commonly used together — use drag-and-drop to reposition it. ![Search for and add the Referrals V2 (Suger) navigation item](images/how-to-configure-your-salesforce-for-ref-3.gif) 1. Click **Save** to apply your new navigation layout. ### Accessing and Using Referrals After saving, you'll see the **Referrals** tab in your navigation bar. Click the tab to view and manage referrals, and use the **Recently Viewed** dropdown to switch between: - **All Referrals** - **Inbound Referrals** – Opportunities shared with you from AWS - **Outbound Referrals** – Opportunities your team has shared with AWS ![Switch between All, Inbound, and Outbound referrals using the Recently Viewed dropdown](images/how-to-configure-your-salesforce-for-ref-4.gif) Referrals saved as a **Draft** and not yet submitted are listed in these views alongside submitted ones, so you can find and finish them from the same table. A draft does not exist on the cloud partner's side yet, so its **Partner Status** and **Stage** columns show `-` until it is submitted. Drafts appear in Salesforce only — the co-sell list in the Fours console omits them. --- ## How Funding records open Opening a **Funding** record from anywhere in Salesforce — a list view, a related list, global search, or a report — redirects to the Suger **Funding Detail** page rather than the standard Salesforce record layout, so you always land on the live Fours view of the funding application. The redirect uses the record's Fours funding application ID, the same value the funding cards and tables link with. If the redirect cannot resolve (for example the record is not readable under your permission set), Salesforce falls back to the standard record view. **Find a Funding record.** Funding records are returned by Salesforce global search, and each result shows the **Funding Application ID**, **Partner**, **AWS Funding Program**, **AWS Activity Name**, **AWS Funding Request Status**, **Approval Status**, **Opportunity**, **AWS Planned Start Date**, and **AWS Planned End Date**. The Fours app also has a tab for the Funding object itself, placed just before **Funding V2 (Suger)** in the app's navigation; its **All** list view shows **Funding Name** plus those nine columns. **Funding V2 (Suger)** (formerly **Funding (Suger)**) is the funding table that reads straight from Fours, and its **Project Name** links open the Funding Detail page. The **Suger Funding** and **Suger Funding (Read Only)** permission sets make both tabs visible. On a cash-based MDF or POC request, the Funding Detail page has a **Cash Claim** section with one tab per planned claim (**Activity 1**, **Activity 2**, … on MDF; **Cash Claim 1**, … on POC). Each tab shows the claim filed for it — its **Fund Claim Id**, **Cash Claim Status**, and **Claim Due Date** — and on an MDF request an **Invoice & Payment** block with **Invoice Currency**, **Invoice Amount (Local Currency)**, and **Scheduled Paid Date**. AWS records each cash claim as its own application linked to the request, and the page reads those claims when it opens, so the values match the Fours Console. A tab whose claim has not been filed yet, or cannot be matched to it, shows a dash in those fields. The same claim dates also sync to the `FundingCashClaim__c` record once AWS records them. On an MDF or POC cash request, the **Cash Request Information** section shows the request's **PO Number** and its **Payee Central Account Profile ID** — the purchase order AWS issued and the Payee Central profile the cash is paid to. Both also sync to the Funding record ([Funding__c](/salesforce-app/salesforce-app-custom-objects/#funding__c)). **Funding stage.** Once AWS reports a stage for the request, the Funding Detail page shows a progress bar with the six stages AWS Partner Central shows for a fund request, in this order. The progress bar shows only the stage names; the diagram adds, under each, the stage value AWS records that maps to it: ```d2 direction: right create: "Application creation\nany other value" business: "Business approval\nBUSINESS_APPROVAL" finance: "Finance approval\nFINANCE_APPROVAL" pre: "Pre-approval\nPRE_APPROVAL" cash: "Cash claim\nInvoice or Disbursement" done: "Application completion\nFULFILLMENT" create -> business -> finance -> pre -> cash -> done ``` The **Funding Stage** on the funding cards in Suger Account Insights and the Suger Opportunity Quick Panel, and the **Stage** column of the **Funding V2 (Suger)** table, use the same names for the five mapped stages, **Business approval** through **Application completion**. They show `-` when AWS has reported no stage, and show any other value exactly as AWS sent it. The table's **Fund Request Stage** filter splits cash claims into **Cash claim (invoice)** and **Cash claim (disbursement)**. --- ## Widget Pin Control In the Opportunity quick panel, each user can pin up to two sections (Offers, Entitlements, Co-Sell, Associated Contacts, Funding) to a **Pinned** tab for quick access. By default this is controlled individually per user. Admins can instead enforce a company-wide set of pinned sections. When enabled, the chosen sections are pinned for every user, and individual users can no longer pin or unpin their own sections. Disabling it again restores each user's previous personal pins. **How to Configure:** 1. Open the Salesforce Suger App and navigate to the **Suger** tab. 1. In the settings menu, scroll down to the **Widget Pin Control** section. 1. Turn ON **Enable Widget Pin Lock**. 1. Select up to two sections to pin company-wide. 1. Click **Save**. :::note Configuring Widget Pin Control requires the **Modify Settings** custom permission (System Administrators have it by default). ::: --- Source: https://doc.fours.com/salesforce-app/salesforce-app-custom-objects/ # Custom Objects This guide documents all custom objects in the Fours Salesforce App. These objects store marketplace data synced from AWS, Azure, GCP, and Snowflake marketplaces. :::note This is a reference article — it documents what exists, not how to set things up. If you're looking for how to install and configure the app, start with [Install the Fours App from Salesforce AppExchange](/salesforce-app/salesforce-app-install/). ::: ## How to Read the Field Tables Every field table below carries a **Populated From** column: the source value Fours writes into that Salesforce field, and any conversion applied on the way. | What you see | What it means | | ------------ | ------------- | | `buyer.info.companyInfo.emailDomain` | The source field. For partner objects this is the **cloud partner's own API field**, so you can match it against what you see in AWS Partner Central, Microsoft Partner Center, or Google Cloud Channel | | `…`, `;`-joined | The source is a list; Fours writes it as a semicolon-separated multi-select value | | `…`, comma-joined | The source is a list; Fours writes it as a comma-separated text value | | `…`, JSON-serialized | The source is a nested object or array; Fours writes it as a JSON string into a Long Text Area | | `…` → `Yes`/`No` | The source is a boolean; Fours writes the literal text `Yes` or `No` | | expanded to the full country name | A two-letter country code is expanded (`US` → `United States`) | | **AWS only** / **Azure** / **GCP** | The field is only populated for that cloud partner. It stays empty for the others | | **Invitation only** / **Post-accept only** | The field belongs to one wave of a two-wave sync — see the timing notes on the Referral and Lead objects | | — not populated by sync | Fours never writes this field. It exists in the package for backward compatibility or is set by hand. **Do not build reports or automation that depend on it** | | lookup resolved by … | A relationship field. Fours resolves the referenced record and links it; the link is left unset if that record has not reached Salesforce yet | :::note Fields are populated on a **best-effort** basis: when the cloud partner does not supply a value, Fours leaves the Salesforce field untouched rather than blanking it. An empty field therefore means "the partner did not send this", not "the sync failed". ::: ## Which Partners Populate Which Objects | Object | AWS | Azure | GCP | Fours Co-Sell | | ------ | --- | ----- | --- | ------------- | | Buyer, Product, Offer, Entitlement, EntitlementTerm, RevenueRecord, OfferDimension, OfferPaymentInstallment | Yes | Yes | Yes | — | | Referral | Yes | Yes | Yes | Yes | | Contact | Yes | Yes | Yes | Yes | | Contact_Account, Contact_Opportunity | Yes | Yes | Yes | Yes | | Lead | Yes | — | — | — | | Funding, FundingCashClaim | Yes | — | — | — | The Referral object splits its fields by prefix — `AWS_`, `AZURE_`, `GCP_`, `PRM_` — and **only the prefix block matching the referral's partner is populated**. A referral from AWS leaves every `AZURE_`, `GCP_` and `PRM_` field empty, and vice versa. The unprefixed Common Fields populate for every partner. Referral_Bulk_Share_Job, Suger_Organization, View, and the three lookup-filter metadata types are written by the app itself or by your admins rather than by the marketplace sync, so their tables carry no **Populated From** column. ## Object Categories | Category | Objects | What it covers | | -------- | ------- | -------------- | | Core Marketplace | Buyer, Product, Offer, Entitlement, EntitlementTerm, RevenueRecord, OfferDimension, OfferPaymentInstallment, Opportunity_Offer | The full lifecycle of a marketplace deal — from product listing to active contract and revenue | | Co-Sell | Referral, Contact, Contact_Account, Contact_Opportunity, Lead, Referral_Bulk_Share_Job | Partner referrals, partner contacts and the accounts and opportunities they cover, leads, and co-sell programs across AWS, Azure, and GCP | | Funding | Funding, FundingCashClaim | Funding programs and cash/credit claims from cloud partners | | Configuration | Suger_Organization, View | App-wide settings and saved list view configurations | | Custom Metadata | Referral_Lookup_Filter__mdt, Entitlement_Lookup_Filter__mdt, Offer_Lookup_Filter__mdt | Admin-configurable lookup filters for the Referral object, and for the **Link** Opportunity pickers on entitlements and offers | ## Object Relationship Overview The Fours data model centers around marketplace transactions across multiple cloud platforms: ```d2 direction: right Product__c -> Offer__c Product__c -> Buyer__c Offer__c -> Entitlement__c Offer__c -> OfferDimension__c Offer__c -> OfferPaymentInstallment__c Entitlement__c -> EntitlementTerm__c Entitlement__c -> RevenueRecord__c Lead__c -> Referral__c Referral__c -> Funding__c Referral__c -> Contact__c Contact__c -> Contact_Account__c Contact__c -> Contact_Opportunity__c Funding__c -> FundingCashClaim__c ``` --- ## Core Marketplace Objects ### Buyer__c Represents cloud marketplace customers/buyers who purchase products through AWS, Azure, GCP, or Snowflake marketplaces. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | ID | `Buyer_ID__c` | Text (External ID) | `buyer.id` | The Buyer ID in Fours service | | Partner | `Partner__c` | Picklist | `buyer.partner` | The partner of the Buyer, such as AWS, AZURE, or GCP | | Creation Date | `Buyer_Creation_Date__c` | Date | `buyer.creationTime` | The creation date of the buyer in Fours service | | Description | `Buyer_Description__c` | Long Text Area | `buyer.description` | The description of the buyer | | Info | `Buyer_Info__c` | Long Text Area | `buyer.info` (full JSON) | The detailed info of the buyer | | Email Domain | `Buyer_Email_Domain__c` | Text | `buyer.info.companyInfo.emailDomain` | The company email domain of the buyer | | Location | `Buyer_Location__c` | Text | `buyer.info.companyInfo.city` + `.country` | The company location of the buyer | | External ID | `Buyer_External_ID__c` | Text | `buyer.externalId` | The buyer's external ID from Cloud Marketplaces | | Buyer Email Address | `Buyer_Email_Address__c` | Text | `buyer.info.emailAddress` | Email address of the buyer | | Contact IDs | `Contact_IDs__c` | Text Area | `buyer.contactIds` (comma-joined) | The contact IDs of the buyer, comma-separated | --- ### Product__c Represents products listed across cloud marketplaces. Products are the foundation for creating offers. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | ID | `Product_ID__c` | Text (External ID) | `product.id` | The product ID in Fours | | Partner | `Partner__c` | Picklist | `product.partner` | The cloud partner where this product is listed | | Type | `Product_Type__c` | Text | `product.productType` | The type of this product | | Status | `Product_Status__c` | Text | `product.status` | The status of this product listing in the Cloud Marketplace | | Creation Date | `Product_Creation_Date__c` | Date | `product.creationTime` | When the Product is listed in the Cloud Marketplace | | Info | `Product_Info__c` | Long Text Area | `product.info` (full JSON) | The detailed info of product, including the price info | | External ID | `Product_External_ID__c` | Text | `product.externalId` | The product external ID from the Cloud Marketplaces | | Fulfillment URL | `Product_Fulfillment_URL__c` | URL | `product.fulfillmentUrl` | The fulfillment URL of the product to signup | | Partner ID | `Partner_ID__c` | Text | — set by the Product sync | Partner ID | --- ### Offer__c Represents marketplace offers (private offers, CPPO, etc.) with approval workflows and expiration tracking. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | ID | `Offer_ID__c` | Text (External ID) | `offer.id` | The unique ID of the Offer. Generated by Fours service | | Partner | `Partner__c` | Picklist | `offer.partner` | The partner where this offer is created (AWS, AZURE, GCP, ALIBABA) | | Partner ID | `Partner_ID__c` | Text | `offer.partnerId` | The seller marketplace integration account that owns this offer. For AWS, this is the 12-digit seller AWS account ID | | Offer Status | `Offer_Status__c` | Text | `offer.status` | The status of this Offer | | External Status | `Offer_External_Status__c` | Text | `offer.externalStatus` | The raw status last reported by the cloud marketplace (e.g. AWS Catalog API entity state: Draft, Active, Released), verbatim — distinct from Offer Status, which Fours derives for its own business logic | | Approval Status | `Approval_Status__c` | Picklist | `offer.metaInfo.approvalInfo.status` | Approval Status (Not Submitted, Submitted, Approved, Declined, Action Required) | | Type | `Offer_Type__c` | Text | `offer.offerType` | The type of this Offer from the cloud marketplaces | | Product ID | `Product_ID__c` | Text | `offer.productId` | The ID of Product where this Offer is based on | | Product Name | `Product_Name__c` | Text | resolved from the linked `Suger__Product__c` | The name of the Product where this Offer is based on | | Product | `Product__c` | Lookup | lookup resolved by `offer.productId` | Reference to Product record | | Buyer | `Buyer__c` | Lookup | lookup resolved by `offer.buyerId` | Reference to Buyer record | | Buyer ID | `Buyer_ID__c` | Text | `offer.buyerId` | Buyer ID | | Buyer Name | `Buyer_Name__c` | Text | resolved from the linked `Suger__Buyer__c` | The name of the Buyer of this Offer | | Buyer Account ID | `Buyer_Account_ID__c` | Text | **AWS** `info.buyerAwsAccountIds[0]` · **Azure** `info.azurePrivateOffer.beneficiaries[0].id` · **GCP** `info.gcpPrivateOffer.customerInfo.unverifiedBillingAccount` | For AWS: Buyer AWS Account ID. For Azure: Beneficiary ID. For GCP: Customer Billing Account ID | | Buyer AWS Account ID | `Buyer_AWS_Account_ID__c` | Text | **AWS only** — `info.buyerAwsAccountIds[0]` | Buyer AWS Account ID | | Offer Info | `Offer_Info__c` | Long Text Area | `offer.info` (full JSON) | The detailed info of this Offer, including the price info | | AWS Net Payment Term | `AWS_Net_Payment_Term__c` | Text (32) | **AWS only** — derived from `info.paymentSchedule` net-term days | For an AWS private or downstream CPPO offer, the buyer term (`Net 15` through `Net 120`). For a CPPO_OUT or synchronized CPPO_IN resale authorization, the maximum allowed term (`Maximum Net 15` through `Maximum Net 120`). Empty means no custom AWS term. | | Meta Info | `Offer_Meta_Info__c` | Long Text Area | `offer.metaInfo` (full JSON) | The meta info of this Offer, populated by Fours service | | External ID | `Offer_External_ID__c` | Text | `offer.externalId` | The external ID of this Offer in the cloud marketplaces | | Creation Date | `Offer_Creation_Date__c` | Date | `offer.creationTime` | When this Private Offer is created in the Cloud Marketplace | | Marketplace Creation Date Time | `Marketplace_Creation_DateTime__c` | DateTime | `offer.metaInfo.offerCreationSuccessDate` | The date and time when this offer was created | | Acceptance DateTime | `Acceptance_DateTime__c` | DateTime | `offer.metaInfo.offerAcceptDate` | When the buyer accepted the offer | | Contract Start Time | `Contract_Start_Time__c` | Date | **Azure** `info.azurePrivateOffer.start` · **AWS/GCP** derived from the offer's contract terms | The contract start time for this offer. For GCP, the calendar day GCP's Producer Portal shows (a Pacific day), not the UTC date of the buyer's acceptance time | | Contract End Time | `Contract_End_Time__c` | Date | **Azure** `info.azurePrivateOffer.end` · **AWS/GCP** derived from the offer's contract terms | The contract end time for this offer. For GCP, taken from the offer's own term, on the same Pacific calendar day GCP's Producer Portal shows | | Offer Duration (Months) | `Offer_Duration_Months__c` | Number (Formula) | Salesforce formula over Contract Start/End — **GCP only** | Calendar months from Contract Start Time to the day after Contract End Time — the end date is the term's last day, so a 6-month term from Oct 1 to Mar 31 reads 6. Only populated for GCP offers. | | Expire Date | `Offer_Expire_Date__c` | Date | `offer.expireTime` | The date when the Offer expires. Cannot be accepted after expiration | | Approval Date | `Approval_Date__c` | Date | — set by the Offer sync | Date when the offer was approved | | Opportunity | `Opportunity__c` | Lookup | `offer.metaInfo.salesforceOpportunityId` | Reference to Salesforce Opportunity | | Account | `Account__c` | Lookup | derived from the linked Opportunity's Account | Account associated with the offer, auto-populated from the linked Opportunity's account, or the directly-linked account when there is no opportunity | | Quote (Deprecated) | `Quote__c` | Text | — deprecated | Deprecated - use QuoteLookup instead | | Quote Lookup | `QuoteLookup__c` | Lookup | `offer.metaInfo.salesforceQuoteId` | The Quote binding to this offer | | Created By | `Created_By__c` | Lookup | Salesforce User matched on the Fours creator's email | Salesforce User who created this offer in Fours marketplace | | Created By Email | `Created_By_Email__c` | Text | Fours creator's email (fallback when no User matches) | Email of the user who created this offer (fallback when no matching Salesforce User) | | Error Message | `Error_Message__c` | Long Text Area | `offer.metaInfo.errorMessages` (joined) | Error Message | | Review Comment | `Review_Comment__c` | HTML | `offer.metaInfo.approvalInfo.message` | Review Comment | | Reseller ID | `Reseller_ID__c` | Text | **AWS** `info.awsChannelPartner.id` · **Azure** `info.azurePrivateOffer.partners[0].id` · **GCP** `info.gcpResellerPrivateOfferPlan.resellerInfo.billingAccountId` | The reseller ID for CPPO (Channel Partner Private Offer) offers | | Offer Visibility | `Offer_Visibility__c` | Text | derived from `offer.offerType` | Whether this is a public marketplace listing offer (PUBLIC) or a private offer negotiated with a specific buyer (PRIVATE) | | Offer Delivery Method | `Offer_Delivery_Method__c` | Text | derived from `offer.offerType` | Whether this is a public marketplace listing offer (PUBLIC) or a private offer negotiated with a specific buyer (PRIVATE) | | SubStatus | `Offer_SubStatus__c` | Text | `offer.subStatus` | The sub-status of this offer | | Is Renewal | `Is_Renewal__c` | Checkbox | derived from `offer.offerType` | Whether this offer is a renewal | | Gross Contract Value | `Gross_Contract_Value__c` | Currency | computed from the offer's pricing (installments, commits, or plan) | Total contract value computed from the offer's pricing data (installments, commits, or plan pricing) | | Marketplace Fee | `Marketplace_Fee__c` | Currency | computed once the first cloud invoice is confirmed | Cloud marketplace commission fee, computed once the first invoice is confirmed | | Net Contract Value | `Net_Contract_Value__c` | Currency | Gross Contract Value − Marketplace Fee | Net amount the seller receives after marketplace commission fees (null until the first cloud invoice is confirmed) | | Marketplace Offer URL | `Marketplace_Offer_URL__c` | URL | `offer.info.privateOfferUrl` | The private offer URL in the cloud marketplace | | Created Source | `Created_Source__c` | Text | `offer.metaInfo.createdBySource` | Source system that created this offer (Suger Console, Salesforce, HubSpot, API, Cloud Partner, or Auto Share) | --- ### Entitlement__c Represents customer entitlements in cloud marketplaces after offer acceptance. Tracks active subscriptions and usage. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | ID | `Entitlement_ID__c` | Text (External ID) | `entitlement.id` | The Entitlement ID in Fours | | Partner | `Partner__c` | Picklist | `entitlement.partner` | The cloud partner where the entitlement is created | | Partner ID | `Partner_ID__c` | Text | `entitlement.partnerId` | The seller marketplace integration account that owns this entitlement. For AWS, this is the 12-digit seller AWS account ID | | Status | `Entitlement_Status__c` | Text | `entitlement.status` | The status of the Entitlement in the Cloud Marketplace | | Type | `Entitlement_Type__c` | Text | `entitlement.type` | The type of the Entitlement | | Product ID | `Product_ID__c` | Text | `entitlement.productId` | The ID of Product where this Entitlement is based on | | Product Name | `Product_Name__c` | Text | resolved from the linked `Suger__Product__c` | The name of the Product where this Entitlement is based on | | Product | `Product__c` | Lookup | lookup resolved by `entitlement.productId` | Reference to Product record | | Offer ID | `Offer_ID__c` | Text | `entitlement.offerId` | The ID of the Offer in this Entitlement | | Offer Name | `Offer_Name__c` | Text | resolved from the linked `Suger__Offer__c` | The name of the Offer in this Entitlement | | Offer | `Offer__c` | Lookup | lookup resolved by `entitlement.offerId` | Reference to Offer record | | Buyer ID | `Buyer_ID__c` | Text | `entitlement.buyerId` | The ID of Buyer in this Entitlement | | Buyer Name | `Buyer_Name__c` | Text | resolved from the linked `Suger__Buyer__c` | The name of the Buyer in this Entitlement | | Buyer | `Buyer__c` | Lookup | lookup resolved by `entitlement.buyerId` | Reference to Buyer record | | Buyer Account ID | `Buyer_Account_ID__c` | Text | **AWS** buyer AWS account · **Azure** beneficiary ID · **GCP** customer billing account | Normalized buyer account identifier across all cloud partners — the AWS Account ID, the Azure billing account ID, or the GCP billing account ID, depending on the partner | | AWS Account ID | `AWS_Account_ID__c` | Text | **AWS only** — buyer AWS account ID | AWS Account ID | | AWS License ARN | `AWS_License_ARN__c` | Text | **AWS only** — `entitlement.info.awsLicenseArn` | The AWS License Manager ARN of the license backing this entitlement's AWS Marketplace agreement. Empty for non-AWS entitlements | | AWS Net Payment Term | `AWS_Net_Payment_Term__c` | Text (32) | **AWS only** — derived from `entitlement.info.awsNetPaymentTerm` | The accepted AWS net payment term for this entitlement, in the same format as the Offer field: `Net 15` through `Net 120`, or the maximum allowed term (`Maximum Net 15` through `Maximum Net 120`) when the entitlement's offer is a CPPO_OUT or CPPO_IN resale authorization. Re-derived on every sync: Fours clears it when the entitlement has no term on record or the term is not one of those six, so an empty value means Fours has no valid accepted AWS payment term to sync. Not on the packaged page layouts | | Entitlement Info | `Entitlement_Info__c` | Long Text Area | — **deprecated**, no longer synced | The detailed info of Entitlement, including the price info | | Meta Info | `Entitlement_Meta_Info__c` | Long Text Area | — **deprecated**, no longer synced | The meta info of the Entitlement, populated by Fours service | | External ID | `Entitlement_External_ID__c` | Text | `entitlement.externalId` | The Entitlement's external ID from the Cloud Marketplaces | | Creation Date | `Entitlement_Creation_Date__c` | Date | `entitlement.creationTime` | Creation date of the entitlement's **current term** — taken from the term's linked offer — falling back to the entitlement's own creation date when there is no term. After a renewal this reflects the latest term, not the original one | | Start Date | `Entitlement_Start_Date__c` | Date | `entitlement.startTime` | Start date of the entitlement's **current term**, falling back to the entitlement's own start date when there is no term. After a renewal this reflects the latest term, not the original one. For GCP, the Pacific calendar day GCP's Producer Portal shows, not the UTC date of the acceptance time | | End Date | `Entitlement_End_Date__c` | Date | `entitlement.endTime` | When the Entitlement was or will be ended. For an active GCP entitlement, Fours keeps this in step with its linked offer's term end and sends it again when that end changes | | Opportunity | `Opportunity__c` | Lookup | resolved from the source Offer's linked Opportunity | Opportunity associated with the entitlement | | Invoiced Amount | `Invoiced_Amount__c` | Currency | `entitlement.info.invoicedAmount` | Cumulative amount invoiced to the buyer for this entitlement across all billing periods | | Collectable Amount | `Collectable_Amount__c` | Currency | `entitlement.info.collectableAmount` | Cumulative amount the marketplace is expected to collect from the buyer for this entitlement | | Disbursed Amount | `Disbursed_Amount__c` | Currency | `entitlement.info.disbursedAmount` | Cumulative amount the marketplace has disbursed to the seller for this entitlement | | Offer Visibility | `Offer_Visibility__c` | Text | derived from the source offer type | Whether this entitlement originated from a public listing offer (PUBLIC) or a private offer (PRIVATE); derived from the linked offer | | Offer Delivery Method | `Offer_Delivery_Method__c` | Text | derived from the source offer type | Whether this entitlement originated from a public listing offer (PUBLIC) or a private offer (PRIVATE); derived from the linked offer | | Account | `Account__c` | Lookup | `entitlement.metaInfo.salesforceAccountId`, else the linked Opportunity's Account | Account associated with the entitlement, populated by the sync with opportunity precedence: the linked Opportunity's account, else the offer's directly-linked account | | Auto Renew | `Auto_Renew__c` | Picklist | `Yes`/`No` from the entitlement's auto-renew flag | Whether Auto Renew is enabled for this entitlement in the cloud marketplace | | Buyer and Reseller | `Buyer_And_Reseller__c` | Text | Salesforce formula over Buyer + Reseller ID | Combined buyer and reseller display value | | Reseller ID | `Reseller_ID__c` | Text | **AWS only** — `entitlement.info.awsChannelPartner.id` | The channel partner (seller of record) on this entitlement's underlying AWS Marketplace agreement — written for AWS CPPO. Empty when the entitlement has no channel partner, such as a direct private offer or a non-CPPO agreement-based offer | | Display Name with Status | `Display_Name_With_Status__c` | Formula (Text) | Salesforce formula over Name + Status | The entitlement display name combined with its status, for list views and lookups | :::note **The record Name, Start Date, and Creation Date follow the current term, not the original contract.** All three are projected from the entitlement's current term and its linked offer, and fall back to the entitlement's own values only when there is no term. After a renewal they describe the **latest** term — so a renewed entitlement will not show the date the customer first bought. When you need the original contract, read the earliest `EntitlementTerm__c` record for that entitlement, or the offer it started from. ::: --- ### EntitlementTerm__c Tracks specific terms, commitments, and credits for entitlements over their lifecycle. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Entitlement Term ID | `Entitlement_Term_ID__c` | Text (External ID) | `entitlementTerm.id` | Entitlement Term ID | | Entitlement | `Entitlement__c` | Lookup | lookup resolved by the parent entitlement ID | Reference to parent Entitlement | | Offer ID | `Offer_ID__c` | Text | `entitlementTerm.offerId` | Offer ID | | Type | `Type__c` | Text | `entitlementTerm.info.type` | Type (subscription, usage, commitment, credit) | | Start Time | `StartTime__c` | DateTime | `entitlementTerm.startTime` | Term start time | | End Time | `EndTime__c` | DateTime | `entitlementTerm.endTime` | Term end time | | Commit Amount | `Commit_Amount__c` | Number | `entitlementTerm.commitAmount` | Commitment amount | | Used Commit Amount | `Used_Commit_Amount__c` | Number | `entitlementTerm.usedCommitAmount` | Used portion of commitment | | Credit Amount | `Credit_Amount__c` | Number | `entitlementTerm.creditAmount` | Credit amount | | Used Credit Amount | `Used_Credit_Amount__c` | Number | `entitlementTerm.usedCreditAmount` | Used portion of credits | | Reported Amount | `Reported_Amount__c` | Number | `entitlementTerm.reportedAmount` | Reported usage amount | --- ### RevenueRecord__c Tracks financial transactions and commission tracking for cloud marketplace deals. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Revenue Record ID | `Revenue_Record_ID__c` | Text (External ID) | `revenueRecord.id` | Revenue Record ID | | Entitlement | `Entitlement__c` | Lookup | lookup resolved by `revenueRecord.entitlementId` (blank when the record is not yet mapped to an entitlement) | Reference to Entitlement | | Revenue Type | `Revenue_Type__c` | Text | — not populated by sync | Type of revenue | | Amount | `Amount__c` | Currency | `revenueRecord.amount` | Transaction amount | | Date | `Date__c` | DateTime | `revenueRecord.date` | Transaction date | | Invoice Amount | `Invoice_Amount__c` | Currency | `revenueRecord.invoiceAmount` | Invoiced amount | | Invoice Date | `Invoice_Date__c` | DateTime | `revenueRecord.invoiceDate` | Invoice date | | Collectable Amount | `Collectable_Amount__c` | Currency | `revenueRecord.collectableAmount` | Amount expected to collect | | Disburse Amount | `Disburse_Amount__c` | Currency | `revenueRecord.disburseAmount` | Amount to be disbursed | | Disburse Date | `Disburse_Date__c` | DateTime | `revenueRecord.disburseDate` | Disbursement date | | Payment Due Date | `Payment_Due_Date__c` | DateTime | `revenueRecord.paymentDueDate` | When payment is due | | Partner Fee Percentage | `Partner_Fee_Percent__c` | Percent | Partner Fee Dollar ÷ invoice amount | Partner fee percentage | | Partner Fee Dollar | `Partner_Fee_Dollar__c` | Currency | marketplace fee on the record | Partner fee in dollars | | Invoice ID | `Invoice_ID__c` | Text | `revenueRecord.info.invoiceID` | The invoice ID associated with this revenue record | | Payment Terms | `Payment_Terms__c` | Text | **AWS** the accepted AWS net payment term (`Net 15` through `Net 120`) when the record carries one · otherwise `Net `, the days from Invoice Date to Payment Due Date | Payment terms for this revenue record | | Usage Period Start Date | `Usage_Period_Start_Date__c` | DateTime | `revenueRecord.info.usagePeriodStartDate` | Start of the usage period this revenue record covers | | Usage Period End Date | `Usage_Period_End_Date__c` | DateTime | `revenueRecord.info.usagePeriodEndDate` | End of the usage period this revenue record covers | --- ### OfferDimension__c Represents metering dimensions on an Offer (the priced units that the offer charges for). Each Offer can have multiple dimensions; this table makes them queryable as first-class records. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Offer Dimension ID | `Offer_Dimension_ID__c` | Text (External ID) | `offer.id` + `dimension.key` (composite; hashed if over 255 chars) | External ID for idempotent upsert. Format: `{offerID}:{key}` (truncated if over 255 chars). | | Offer | `Offer__c` | Lookup | lookup resolved by `offer.id` | Reference to the parent Offer record. | | Offer ID | `Offer_ID__c` | Text | `offer.id` | Fours Offer ID — used to resolve the parent Offer lookup during backfill. | | Key | `Key__c` | Text | `offer.info.dimensions[].key` | API key/identifier of the metering dimension (`MeteringDimension.Key`). | | Category | `Category__c` | Text | `offer.info.dimensions[].category` | Category of the metering dimension. | | Description | `Description__c` | Long Text Area | `offer.info.dimensions[].description` | Human-readable description of the dimension. | | Types | `Types__c` | Text | `offer.info.dimensions[].types` (`;`-joined) | Semicolon-separated list of dimension types (`MeteringDimension.Types`). | | Rate | `Rate__c` | Number | `offer.info.dimensions[].rate` | Unit price of the dimension (`MeteringDimension.Rate`). | | Value Type | `Value_Type__c` | Text | `offer.info.dimensions[].valueType` | **GCP only.** Value type of the metering dimension quantity. | | Plan ID | `Plan_ID__c` | Text | `offer.info.dimensions[].planId` | **GCP only.** ID of the plan that the dimension belongs to. | | Plan Name | `Plan_Name__c` | Text | `offer.info.dimensions[].planName` | **GCP only.** Name of the plan that the dimension belongs to. | | SKU ID | `Sku_ID__c` | Text | `offer.info.dimensions[].skuId` | **GCP only.** SKU ID of the metering dimension. | --- ### OfferPaymentInstallment__c Represents the payment-schedule installments on an Offer (the planned payments a private offer charges for). Each Offer can have multiple installments; this table makes them queryable as first-class records. Populated by the Fours → Salesforce backfill. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Offer Payment Installment ID | `Offer_Payment_Installment_ID__c` | Text (External ID) | `offer.id` + installment index (composite) | External ID for idempotent upsert. Format: `{offerID}:{chargeOn}` (or `{offerID}:i{index}` when the charge date is blank). | | Offer | `Offer__c` | Lookup | lookup resolved by `offer.id` | Reference to the parent Offer record. | | Offer ID | `Offer_ID__c` | Text | `offer.id` | Fours Offer ID — used to resolve the parent Offer lookup during backfill. | | Charge Date | `Charge_Date__c` | Date | `installment.chargeOn` | Date the buyer is charged for this installment. Blank means charged on the entitlement's effective date. | | Amount | `Amount__c` | Number | `installment.amount` | Amount charged for this installment, after any discount. | | Original Amount | `Original_Amount__c` | Number | `installment.originalAmount` | List price before discount; blank if there is no discount. | | Discount % | `Discount_Percentage__c` | Number | `installment.discountPercentage` | Discount off the original price, 0 to 100. | | Credit | `Credit__c` | Number | `installment.credit` | **GCP only.** One-time credit applied to this installment. | | Currency | `Currency__c` | Text | `offer.info.currency` | ISO currency code of the installment amounts (e.g. USD, JPY), taken from the parent offer. | --- ### Opportunity_Offer__c Junction object linking a Salesforce **Opportunity** to a Fours **Offer**. Allows a single opportunity to be associated with multiple offers (and vice-versa) when the "Enable Offer Set In Opportunity Level" setting is on. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Offer | `Offer__c` | Master-Detail | — created by the app when an Offer is linked to an Opportunity | Reference to the Offer record. | | Opportunity | `Opportunity__c` | Master-Detail | — created by the app when an Offer is linked to an Opportunity | Reference to the Salesforce Opportunity. | --- ## Co-Sell Objects ### Referral__c Represents partner referrals with extensive platform-specific fields for AWS, Azure, GCP, and Fours PRM co-sell programs. :::note The Referral object contains 175+ fields to accommodate the different data requirements of each cloud partner's co-sell program. Fields are prefixed with `AWS_`, `AZURE_`, `GCP_`, or `PRM_` (Fours partner-to-partner co-sell) to indicate the program they apply to. ::: **How many fields a referral actually fills.** One referral belongs to exactly one partner, so it only ever populates the Common Fields plus its own prefix block: | Referral's partner | Fields populated | Source record | | ------------------ | ---------------- | ------------- | | AWS | Common + up to 84 of the 101 `AWS_` fields | ACE Opportunity, or the Engagement Invitation before you accept | | Azure | Common + 33 of the 35 `AZURE_` fields | Your Microsoft Partner Center referral, plus Microsoft's own copy for the `MS_` fields | | GCP | Common + all 70 `GCP_` fields | Google Cloud Channel Opportunity | | Fours Co-Sell | Common + all 19 `PRM_` fields | The partner-to-partner co-sell opportunity | Every other prefix block stays empty. The counts exclude fields marked *not populated by sync* in the tables below. #### Source Records by Partner Each partner's fields come from a different upstream record. Knowing which one you have tells you which fields can be populated at all. | Partner | Source record | Notes | | ------- | ------------- | ----- | | **AWS** | ACE **Engagement Invitation** *or* ACE **Opportunity** — never both | Mutually exclusive, and which one you have depends on lifecycle stage. A pending invitation fills only 19 fields; accepting it switches the row to the Opportunity's 85. See the breakdown under AWS Fields below | | **Azure** | **Your** Partner Center referral, plus **Microsoft's** copy of the same referral | Both at once, feeding different fields. Of the 35 `AZURE_` fields, **28 come from your copy**, **5 from Microsoft's** (empty until Microsoft's copy exists), and 2 are never populated | | **GCP** | Google Cloud Channel **Opportunity** | A single record. All 70 `GCP_` fields come from it, though many sub-objects (`partnerInfo`, `salesCycle`, `winLossInfo`, `opportunityLines`) are only present after Google approves or closes the opportunity | | **Fours Co-Sell** | The partner-to-partner **co-sell opportunity** | A single record, internal to Fours — no cloud partner involved | **The 5 Azure fields that come from Microsoft's copy, not yours:** `AZURE_MS_ReferralStatus__c`, `AZURE_MS_ReferralSubStatus__c`, `AZURE_Microsoft_Contact_Name__c`, `AZURE_Microsoft_Contact_Email__c`, `AZURE_AssistanceRequestCode__c` Microsoft's copy exists only once Microsoft has engaged with the referral. Until then these five stay empty while your copy's 28 fields are already populated — an empty `AZURE_MS_ReferralStatus__c` means "Microsoft has not engaged yet", not "the sync failed". `AZURE_AssistanceRequestCode__c` is the exception that still gets a value without Microsoft's copy: it defaults to *No help required*. **GCP sub-objects that arrive late.** These `GCP_` fields stay empty until Google approves the opportunity, and are not a sync problem: | Only after approval | Only after close | | ------------------- | ---------------- | | `partnerInfo` — incentive type, distributor, sub-billing account, submitted/approved dates, rebate expiry | `winLossInfo` — win/loss reasons, products, additional context | | `salesCycle` — partner ready to close, close-date push count, PRM site details | | | `opportunityLines`, `opportunityTeamMembers`, `customerContacts`, `rebateExtensions` | | #### Common Fields | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Referral ID | `Referral_ID__c` | Text (External ID) | `referral.id` — all partners | The unique ID of the Referral. Generated by Fours service | | Referral Type | `Referral_Type__c` | Picklist | **AWS** from `Origin` · **Azure** from `direction` · **GCP** always `Outbound` · **Fours** from `direction` | Referral Type (Inbound/Outbound) | | Referral Status | `Referral_Status__c` | Picklist | `referral.status`, mapped to the Salesforce status picklist — all partners | Referral Status | | Partner | `Partner__c` | Picklist | `referral.partner` — all partners | Partner (AWS/AZURE/GCP/SUGER) | | Region | `Region__c` | Text | — not populated by sync | Region | | Account ID | `AccountID__c` | Lookup | `referral.salesforceAccountId` (cleared when unset) — all partners | Reference to Salesforce Account | | Opportunity ID | `OpportunityID__c` | Lookup | `referral.salesforceOpportunityId` (cleared when unset) — all partners | Reference to Salesforce Opportunity | | Last Sync Log | `LastSyncLog__c` | Text Area | — written by the app, not the sync | Last Sync Log | | Creation Status | `Creation_Status__c` | Picklist | derived from `referral.status` — all partners | Creation Status | | Creation Failure Message | `Creation_Failure_Message__c` | Long Text Area | — written by the app on a failed create | Creation Failure Message | | Update Status | `Update_Status__c` | Picklist | `referral.metaInfo.updateStatus` — all partners | Update Status | | Update Failure Message | `Update_Failure_Message__c` | Long Text Area | — written by the app on a failed update | Update Failure Message | | Created Source | `Created_Source__c` | Text | `referral.metaInfo.createdBySource`, formatted for display — all partners | Source system that created this referral (Suger Console, Salesforce, HubSpot, API, Cloud Partner, or Auto Share) | #### AWS Fields ##### Which source record fills them: Engagement Invitation vs ACE Opportunity An AWS referral is written from **one of two AWS records, never both at once**, and which one you have depends on where the deal sits in its lifecycle. Both write to the same `Suger__Referral__c` row. | | Engagement Invitation | ACE Opportunity | | --- | --- | --- | | **When you have it** | AWS has invited you to a deal, and you have not accepted yet | You accepted the invitation, or you created an outbound referral yourself | | **Fields it fills** | **19** — the full list is below | **85** — everything in the topical tables that follows | | **Customer contacts** | Never — the invitation carries no contact PII | `AWS_CustomerFirstName__c` and the other contact fields, shared **10–30 minutes after acceptance**, not immediately | | **Lifecycle / stage** | Never | `AWS_Stage__c`, `AWS_Status__c`, `AWS_AwsStage__c`, next steps, review comments | | **AWS & partner team** | Never | Sales rep, account owner, PDM, ISV/partner success manager, primary contact | | **Marketing, solutions, insights** | Never | Campaign, channels, products, offers, engagement score, quality score | So a **pending invitation gives you 19 fields and nothing else.** Everything else stays empty until you accept. **The complete Engagement Invitation field set** These are every field a pending or rejected invitation can fill. Paths are relative to the ACE `EngagementInvitation`. | API Name | Populated From | | -------- | -------------- | | `Name` | `EngagementTitle` | | `Referral_Type__c` | `SenderCompanyName` — `AWS` ⇒ Inbound, otherwise Outbound | | `AWS_OpportunityOwnership__c` | `SenderCompanyName` — `AWS` ⇒ `AWS Referral`, otherwise `Partner Referral` | | `AWS_CreatedDate__c` | `InvitationDate` | | `AWS_AwsAccountId__c` | `Receiver.Account.AwsAccountId` — **your** account, not the customer's | | `AWS_CustomerCompanyName__c` | `Payload.Customer.CompanyName` | | `AWS_Industry__c` | `Payload.Customer.Industry` | | `AWS_Country__c` | `Payload.Customer.CountryCode`, expanded to the full country name | | `AWS_CustomerWebsite__c` | `Payload.Customer.WebsiteUrl` | | `AWS_PartnerProjectTitle__c` | `Payload.Project.Title` | | `AWS_ProjectDescription__c` | `Payload.Project.BusinessProblem` | | `AWS_TargetCloseDate__c` | `Payload.Project.TargetCompletionDate` | | `AWS_CustomerSoftwareValue__c` | `Payload.Project.ExpectedCustomerSpend[0].Amount` | | `AWS_CustomerSoftwareValueCurrency__c` | `Payload.Project.ExpectedCustomerSpend[0].CurrencyCode` | | `AWS_AcceptBy__c` | `ExpirationDate` — **invitation-only** | | `AWS_PartnerAcceptanceStatus__c` | `Status` → `Pending` / `Accepted` / `Rejected` — **invitation-only** | | `AWS_RejectionReason__c` | `RejectionReason`, only when the invitation was rejected — **invitation-only** | | `AWS_InvitationMessage__c` | `InvitationMessage`, the sender's covering note — **invitation-only** | | `AWS_EngagementInvitationArn__c` | `Arn` — **invitation-only** | `AWS_InvitationMessage__c` is on **both** packaged Referral page layouts (Referral Layout and Referral Layout V2), so the sender's covering note is visible without customizing a layout first. It is a Long Text Area holding up to **32,768 characters**, so the whole message is kept rather than truncated. Of those 19, **12 are re-written from the ACE Opportunity once you accept** (from a different path — for example `AWS_CustomerCompanyName__c` moves from `Payload.Customer.CompanyName` to `Customer.Account.CompanyName`). The **5 marked invitation-only** have no counterpart on the Opportunity, so they keep their invitation values permanently and are how you tell, after the fact, that a referral arrived as an invitation. The topical tables below cover the **ACE Opportunity** field set. Where a field can also come from an invitation, its **Populated From** cell shows both, as `Customer.Account.CompanyName · invitation: Payload.Customer.CompanyName`. **Account & Contact Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | AWS Account ID | `AWS_AwsAccountId__c` | Text | `Customer.Account.AwsAccountId` · invitation: `Receiver.Account.AwsAccountId` | AWS Account ID | | AWS Account Manager Email | `AWS_AwsAccountOwnerEmail__c` | Text | `AWSOpportunityTeam[]` AWSAccountOwner — `Email` | AWS Account Manager Email | | AWS Account Manager Name | `AWS_AwsAccountOwnerName__c` | Text | `AWSOpportunityTeam[]` `AWSAccountOwner` — `FirstName` + `LastName` | AWS Account Manager Name | | Customer Company Name | `AWS_CustomerCompanyName__c` | Text | `Customer.Account.CompanyName` · invitation: `Payload.Customer.CompanyName` | Customer Company Name | | Customer First Name | `AWS_CustomerFirstName__c` | Text | `Customer.Contacts[0].FirstName` | Customer First Name | | Customer Last Name | `AWS_CustomerLastName__c` | Text | `Customer.Contacts[0].LastName` | Customer Last Name | | Customer Email | `AWS_CustomerEmail__c` | Text | `Customer.Contacts[0].Email` | Customer Email | | Customer Phone | `AWS_CustomerPhone__c` | Text | `Customer.Contacts[0].Phone` | Customer Phone | | Customer Title | `AWS_CustomerTitle__c` | Text | `Customer.Contacts[0].BusinessTitle` | Customer Title | | Customer DUNS | `AWS_CustomerDuns__c` | Text | `Customer.Account.Duns` | Customer DUNS | | Customer Website | `AWS_CustomerWebsite__c` | URL | `Customer.Account.WebsiteUrl` · invitation: `Payload.Customer.WebsiteUrl` | Customer Website | | Partner Primary Contact Email | `AWS_PrimaryContactEmail__c` | Text | `OpportunityTeam[]` PartnerAccountManager — `Email` | Partner Primary Contact Email | | Partner Primary Contact First Name | `AWS_PrimaryContactFirstName__c` | Text | `OpportunityTeam[]` where `BusinessTitle` = `PartnerAccountManager` — `FirstName` | Partner Primary Contact First Name | | Partner Primary Contact Last Name | `AWS_PrimaryContactLastName__c` | Text | `OpportunityTeam[]` PartnerAccountManager — `LastName` | Partner Primary Contact Last Name | | Partner Primary Contact Phone | `AWS_PrimaryContactPhone__c` | Text | `OpportunityTeam[]` PartnerAccountManager — `Phone` | Partner Primary Contact Phone | | Primary Contact Title | `AWS_PrimaryContactTitle__c` | Text | `OpportunityTeam[]` PartnerAccountManager — `BusinessTitle` | Primary Contact Title | | AWS ISV Success Manager Email | `AWS_AwsIsvSuccessManagerEmail__c` | Text | `AWSOpportunityTeam[]` ISVSM — `Email` | AWS ISV Success Manager Email | | AWS ISV Success Manager Name | `AWS_AwsIsvSuccessManagerName__c` | Text | `AWSOpportunityTeam[]` `ISVSM` — `FirstName` + `LastName` | AWS ISV Success Manager Name | | AWS Sales Rep Email | `AWS_AwsSalesRepEmail__c` | Text | `AWSOpportunityTeam[]` AWSSalesRep — `Email` | AWS Sales Rep Email | | AWS Sales Rep Name | `AWS_AwsSalesRepName__c` | Text | `AWSOpportunityTeam[]` where `BusinessTitle` = `AWSSalesRep` — `FirstName` + `LastName` | AWS Sales Rep Name | | AWS Partner Success Manager Email | `AWS_AwsPartnerSuccessManagerEmail__c` | Text | `AWSOpportunityTeam[]` PSM — `Email` | AWS Partner Success Manager Email | | AWS Partner Success Manager Name | `AWS_AwsPartnerSuccessManagerName__c` | Text | `AWSOpportunityTeam[]` `PSM` — `FirstName` + `LastName` | AWS Partner Success Manager Name | | WWPS Partner Development Manager | `AWS_WwpsPdm__c` | Text | `AWSOpportunityTeam[]` `WWPSPDM` — `FirstName` + `LastName` | WWPS Partner Development Manager | | WWPS Partner Development Manager Email | `AWS_WwpsPdmEmail__c` | Text | `AWSOpportunityTeam[]` WWPSPDM — `Email` | WWPS Partner Development Manager Email | | Partner Developer Manager | `AWS_PartnerDeveloperManager__c` | Text | `AWSOpportunityTeam[]` `PDM` — `FirstName` + `LastName` | Partner Developer Manager | | AWS Partner Development Manager Email | `AWS_partnerDeveloperManagerEmail__c` | Text | `AWSOpportunityTeam[]` PDM — `Email` | AWS Partner Development Manager Email | | Opportunity Owner | `AWS_OpportunityOwner__c` | Lookup | — not populated by sync | Opportunity Owner | | Opportunity Owner Email | `AWS_OpportunityOwnerEmail__c` | Text | `OpportunityTeam[]` owner — `Email` | Opportunity Owner Email | | Opportunity Owner Name | `AWS_OpportunityOwnerName__c` | Text | `OpportunityTeam[]` owner — `FirstName` + `LastName` | Opportunity Owner Name | **Opportunity & Deal Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Stage | `AWS_Stage__c` | Picklist | `LifeCycle.Stage` | Stage | | Status on AWS | `AWS_Status__c` | Picklist | `LifeCycle.ReviewStatus` | Status on AWS | | AWS Stage | `AWS_AwsStage__c` | Text | `AWSLifeCycle.Stage` | AWS Stage | | Opportunity Type | `AWS_OpportunityType__c` | Picklist | `OpportunityType` | Opportunity Type | | Opportunity Ownership | `AWS_OpportunityOwnership__c` | Picklist | `Origin` — `AWS Referral` ⇒ Inbound, `Partner Referral` ⇒ Outbound | Opportunity Ownership | | Target Close Date | `AWS_TargetCloseDate__c` | Date | `LifeCycle.TargetCloseDate` · invitation: `Payload.Project.TargetCompletionDate` | Target Close Date | | AWS Close Date | `AWS_AwsCloseDate__c` | Date | — not populated by sync | AWS Close Date | | Customer Software Value | `AWS_CustomerSoftwareValue__c` | Currency | `SoftwareRevenue.Value.Amount` · invitation: `Payload.Project.ExpectedCustomerSpend[0].Amount` | Customer Software Value | | Customer Software Value Currency | `AWS_CustomerSoftwareValueCurrency__c` | Picklist | `SoftwareRevenue.Value.CurrencyCode` · invitation: `…ExpectedCustomerSpend[0].CurrencyCode` | Customer Software Value Currency | | Expected Monthly AWS Revenue | `AWS_ExpectedMonthlyAwsRevenue__c` | Number | `Project.ExpectedCustomerSpend[0].Amount` | Expected Monthly AWS Revenue | | Closed Lost Reason | `AWS_ClosedLostReason__c` | Text | `LifeCycle.ClosedLostReason` | Closed Lost Reason | | AWS Closed Lost Reason | `AWS_AwsClosedLostReason__c` | Text | — not populated by sync | AWS Closed Lost Reason | | Rejection Reason | `AWS_RejectionReason__c` | Picklist | **Invitation only** — `RejectionReason` | Rejection Reason | | Parent Opportunity ID | `AWS_ParentOppId__c` | Text | `Project.RelatedOpportunityIdentifier` | Parent Opportunity ID | **Location Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Street | `AWS_StreetAddress__c` | Text | `Customer.Account.Address.StreetAddress` | Street Address | | City | `AWS_City__c` | Text | `Customer.Account.Address.City` | City | | State | `AWS_State__c` | Picklist | `Customer.Account.Address.StateOrRegion` | State | | Postal Code | `AWS_PostalCode__c` | Text | `Customer.Account.Address.PostalCode` | Postal Code | | Country | `AWS_Country__c` | Picklist | `Customer.Account.Address.CountryCode`, expanded to the full country name · invitation: `Payload.Customer.CountryCode` | Country | **Classification & Programs:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Industry | `AWS_Industry__c` | Picklist | `Customer.Account.Industry` · invitation: `Payload.Customer.Industry` | Industry | | Industry (V2) | `AWS_Industry_V2__c` | Text | `Customer.Account.Industry` | New version of the ACE industry | | Industry Other | `AWS_IndustryOther__c` | Text | `Customer.Account.OtherIndustry` | Industry Other | | Use Case | `AWS_UseCase__c` | Picklist | `Project.CustomerUseCase` | Use Case | | Use Case (V14) | `AWS_UseCaseV14__c` | Picklist | — not populated by sync | Use Case (detailed list) | | APN Programs | `AWS_CampaignName__c` | Picklist | — not populated by sync | APN Programs | | APN Programs (V14) | `AWS_CampaignNameV14__c` | Multi-Select Picklist | `Marketing.CampaignName` (an APN program, not a campaign name) | APN Programs | | Delivery Model | `AWS_DeliveryModel__c` | Picklist | `Project.DeliveryModels`, `;`-joined | Delivery Model | | Delivery Model (V14) | `AWS_DeliveryModelV14__c` | Multi-Select Picklist | — not populated by sync | Delivery Model | | Solution Offered | `AWS_SolutionOffered__c` | Multi-Select Picklist | `RelatedEntityIdentifiers.Solutions`, `;`-joined | Solution Offered | | Other Solution Offered | `AWS_OtherSolutionOffered__c` | Text | `Project.OtherSolutionDescription` | Other Solution Offered | | Competitive Tracking | `AWS_CompetitiveTracking__c` | Picklist | `Project.CompetitorName` | Competitive Tracking | | Competitive Tracking Other | `AWS_CompetitiveTrackingOther__c` | Text | `Project.OtherCompetitorNames` | Competitive Tracking Other | | Procurement Type | `AWS_ProcurementType__c` | Picklist | — not populated by sync | Procurement Type | | Contract Vehicle | `AWS_ContractVehicle__c` | Text | — not populated by sync | Contract Vehicle (Public Sector) | | Solicitation Number | `AWS_RfxSolicitationNumber__c` | Text | — not populated by sync | Solicitation Number (Public Sector) | **Marketing & Activities:** :::warning The Customer Business Problem (`AWS_ProjectDescription__c`) and the Partner Project Title (`AWS_PartnerProjectTitle__c`) do **not** behave the same way after submission. - **Customer Business Problem stays editable.** Fours accepts a new value while the referral's review status is **Approved** or **Action Required**, subject to the same 20-character minimum and 2,000-character cap as at creation — a longer value is truncated rather than rejected. - **Partner Project Title is fixed at creation.** The update path never carries a new title to AWS in any review status, so an edit is silently dropped and the referral keeps the title it was created with. To change it, create a new referral. Neither field can be updated once the review status is anything other than Approved or Action Required — a referral in Pending Submission, Submitted, or Rejected rejects the update outright. ::: | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Marketing Campaign | `AWS_AwsSfCampaignName__c` | Text | `Marketing.CampaignName` | Marketing Campaign | | Customer Business Problem | `AWS_ProjectDescription__c` | Long Text Area | `Project.CustomerBusinessProblem` · invitation: `Payload.Project.BusinessProblem` | Customer Business Problem. 20–2,000 character hard cap | | Partner Project Title | `AWS_PartnerProjectTitle__c` | Text | `Project.Title` · invitation: `Payload.Project.Title` | Partner Project Title | | AWS Opportunity ID | `AWS_OpportunityId__c` | Text | `Id` | The AWS-assigned ACE opportunity id. Use this to link an ACE referral created outside Salesforce to a Salesforce opportunity | | Partner CRM ID | `AWS_ApnCrmUniqueIdentifier__c` | Text | `PartnerOpportunityIdentifier` | The opportunity's id in your own CRM, as reported to AWS Partner Central. Cleared when ACE holds no value | | Next Step | `AWS_NextStep__c` | Text Area | `LifeCycle.NextSteps` | Next Step | | Next Step History | `AWS_NextStepHistory__c` | Multi-Select Picklist | `LifeCycle.NextStepsHistory`, JSON-serialized | Next Step History | | Additional Comments | `AWS_AdditionalComments__c` | Text Area | `Project.AdditionalComments` | Additional Comments. 255-character cap | | APN Reviewer Comments | `AWS_ApnReviewerComments__c` | Long Text Area | `LifeCycle.ReviewComments` | APN Reviewer Comments | | AWS Recommended Action | `AWS_RecommendedNextBestActions__c` | Long Text Area | `Insights.NextBestActions` | AWS Recommended Action | | Marketing Activity Channel | `AWS_MarketingActivityChannel__c` | Multi-Select Picklist | `Marketing.Channels`, `;`-joined | Marketing Activity Channel | | Marketing Activity Use-Case | `AWS_MarketingActivityUsecase__c` | Multi-Select Picklist | `Marketing.UseCases`, `;`-joined | Marketing Activity Use-Case | | AWS Products | `AWS_Products__c` | Multi-Select Picklist | `RelatedEntityIdentifiers.AwsProducts`, `;`-joined | AWS Products | | Offers (Deprecated) | `AWS_Offers__c` | Text | — not populated by sync (superseded by `AWS_OffersV2__c`) | Offers (Deprecated) | | Offers | `AWS_OffersV2__c` | Multi-Select Picklist | `RelatedEntityIdentifiers.AwsMarketplaceOffers`, `;`-joined | Offers | | Sales Activities | `AWS_SalesActivities__c` | Multi-Select Picklist | `Project.SalesActivities`, `;`-joined | Sales Activities | **Dates & Status:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | AWS Created Date | `AWS_CreatedDate__c` | Date | `CreatedDate` · invitation: `InvitationDate` | Date when referral was created in AWS Partner Central | | Last Modified Date | `AWS_LastModifiedDate__c` | DateTime | `LastModifiedDate` | Last Modified Date | | Accept By | `AWS_AcceptBy__c` | DateTime | **Invitation only** — `ExpirationDate` | Accept By deadline | | Partner Acceptance Date | `AWS_Partner_Acceptance_Date__c` | DateTime | — not populated by sync | Partner Acceptance Date | | Partner Acceptance Status | `AWS_PartnerAcceptanceStatus__c` | Picklist | **Invitation only** — `Status` mapped to `Pending`/`Accepted`/`Rejected` | Partner Acceptance Status | | Cosell Convert Reason | `AWS_CosellConvertReason__c` | Picklist | — not populated by sync | Cosell Convert Reason | | Contract Start Date | `AWS_ContractStartDate__c` | Date | `SoftwareRevenue.EffectiveDate` | Contract Start Date | | Contract End Date | `AWS_ContractEndDate__c` | Date | `SoftwareRevenue.ExpirationDate` | Contract End Date | **Additional Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Created By | `AWS_CreatedBy__c` | Text | — not populated by sync | Created By | | Last Modified by | `AWS_LastModifiedBy__c` | Text | — not populated by sync | Last Modified by | | Has Classified National Security Info? | `AWS_DoesOppBelongToNatSec__c` | Picklist | `NationalSecurity` | Has Classified National Security Info? | | Is Opportunity from Marketing Activity? | `AWS_IsOppFromMarketingActivity__c` | Picklist | — not populated by sync | Is Opportunity from Marketing Activity? | | Marketing development funds | `AWS_IsMarketingDevelopmentFunded__c` | Picklist | `Marketing.AwsFundingUsed` | Marketing development funds | | Is this for Marketplace? | `AWS_IsThisForMarketplace__c` | Picklist | — not populated by sync | Is this for Marketplace? | | Partner Primary Need from AWS | `AWS_PartnerPrimaryNeedFromAWS__c` | Picklist | — not populated by sync (superseded by the V14 field) | Partner Primary Need from AWS | | Partner Primary Need from AWS (V14) | `AWS_PartnerPrimaryNeedFromAwsV14__c` | Multi-Select Picklist | `PrimaryNeedsFromAws`, `;`-joined | Partner Primary Need from AWS | | AWS Engagement Invitation ARN | `AWS_EngagementInvitationArn__c` | Text | **Invitation only** — `Arn` | AWS Engagement Invitation ARN | | Invitation Message | `AWS_InvitationMessage__c` | Long Text Area | **Invitation only** — `InvitationMessage` | Message the sender attached to the engagement invitation | | AWS Marketplace Engagement Score | `AWS_EngagementScore__c` | Picklist | `Insights.EngagementScore` | AWS's own engagement score for the opportunity. Set only when AWS scores it, so blank means AWS has not scored it yet. Fours' own **Suger Predicted Engagement Score** is not stored here (the field's help text says the same) | | AWS Co-Sell Motion | `AWS_CosellMotion__c` | Text (40) | `CosellMotion` | The co-sell motion AWS assigned to the opportunity. Scored asynchronously — blank until AWS returns it | | AWS Opportunity Quality Score | `AWS_OpportunityQualityScore__c` | Number | `Insights.OpportunityQuality.Score` | AWS's quality score for the opportunity. Scored asynchronously — blank until AWS returns it | | AWS Opportunity Quality Trend | `AWS_OpportunityQualityTrend__c` | Text (20) | `Insights.OpportunityQuality.Trend` | Direction the quality score is moving. Scored asynchronously — blank until AWS returns it | | AWS Recommendations | `AWS_Recommendations__c` | Long Text Area | `Insights.Recommendations`, JSON-serialized | AWS's recommended actions, as a JSON array of `{Type, Details, Attributes}` objects | #### Azure Fields **Customer Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Customer Company Name | `AZURE_CustomerCompanyName__c` | Text | `customerProfile.name` | Customer Company Name | | Customer First Name | `AZURE_CustomerFirstName__c` | Text | `customerProfile.team[0].firstName` | Customer First Name | | Customer Last Name | `AZURE_CustomerLastName__c` | Text | `customerProfile.team[0].lastName` | Customer Last Name | | Customer Email | `AZURE_CustomerEmail__c` | Text | `customerProfile.team[0].email` | Customer Email | | Customer Phone | `AZURE_CustomerPhone__c` | Text | `customerProfile.team[0].phoneNumber` | Customer Phone | | Customer Title | `AZURE_CustomerTitle__c` | Text | `customerProfile.team[0].title` | Customer Title | **Location Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Street | `AZURE_StreetAddress__c` | Text | `customerProfile.address.addressLine1` | Street Address | | City | `AZURE_City__c` | Text | `customerProfile.address.city` | City | | State | `AZURE_State__c` | Picklist | `customerProfile.address.state` | State | | Postal Code | `AZURE_PostalCode__c` | Text | `customerProfile.address.postalCode` | Postal Code | | Country (Deprecated) | `AZURE_Country__c` | Picklist | — not populated by sync (use `AZURE_Country_Code__c`) | Country (Deprecated) | | Country Code | `AZURE_Country_Code__c` | Text | `customerProfile.address.country` | Country Code | **Referral Status & Type:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Microsoft Referral ID | `AZURE_ReferralId__c` | Text | `id` | Microsoft Referral ID | | Status on Microsoft | `AZURE_ReferralStatus__c` | Text | `status` | Status on Microsoft | | SubStatus on Microsoft | `AZURE_ReferralSubStatus__c` | Text | `subStatus` | SubStatus on Microsoft | | Microsoft Acceptance Status | `AZURE_MS_ReferralStatus__c` | Text | **Microsoft's copy only** — `status` | Status shown to Microsoft Sales Reps (New, Active, Closed) | | Microsoft Acceptance Sub-Status | `AZURE_MS_ReferralSubStatus__c` | Text | **Microsoft's copy only** — `subStatus` | Acceptance status (Pending, Received, Accepted, Declined, Lost, Won, Expired, Error) | | Microsoft Sales Stage | `AZURE_SalesStage__c` | Text | `salesStage`, mapped to its display name (defaults to `Prospecting`) | Microsoft Sales Stage | | Microsoft Referral Type | `AZURE_Type__c` | Text | `type` | Microsoft Referral Type | **Deal & Solution Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Solution Area | `AZURE_Solution_Area__c` | Text | derived from the referral's solution area | Solution Area | | Solution Play | `AZURE_Solution_Play__c` | Text | derived from the referral's solution play | Solution Play | | Microsoft Referral Campaign ID | `AZURE_CampaignId__c` | Text | `campaignId` | Microsoft Referral Campaign ID | | Help from Microsoft | `AZURE_AssistanceRequestCode__c` | Text | **Microsoft's copy only** — `inviteContext.assistanceRequestCode`, mapped to its display name (defaults to *No help required*) | Help from Microsoft | | Help Type (Deprecated) | `AZURE_AssitanceRequresCode__c` | Text | — not populated by sync — misspelled legacy field, superseded by `AZURE_AssistanceRequestCode__c` | Help Type (Deprecated) | | Deal Value | `AZURE_DealValue__c` | Number | `details.dealValue` | Deal Value | | MACC Eligible (Deprecated) | `AZURE_MACC_Eligibility__c` | Checkbox | `customerProfile.isMaccEligible` (raw boolean) | MACC Eligible (Deprecated) | | MACC Eligible | `AZURE_MACC_EligibilityV2__c` | Picklist | `customerProfile.isMaccEligible` → `Yes`/`No` | MACC Eligible | | Target Close Date | `AZURE_TargetCloseDate__c` | Date | `details.closingDateTime` | Target Close Date | **Microsoft Contact & Metadata:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Microsoft Contact Email | `AZURE_Microsoft_Contact_Email__c` | Email | **Microsoft's copy only** — `team[0].email` | Microsoft Contact Email | | Microsoft Contact Name | `AZURE_Microsoft_Contact_Name__c` | Text | **Microsoft's copy only** — `team[0].firstName` + `lastName` | Microsoft Contact Name | | Microsoft Created Date/Time | `AZURE_Created_Date_Time__c` | DateTime | `createdDateTime` | Date/time referral was created on Microsoft Partner Center | | Microsoft Referral Info | `AZURE_Referral_Info__c` | Long Text Area | the full Microsoft referral set, JSON-serialized | Microsoft Referral Info | | Deal Registration Eligible | `AZURE_DealReg_Eligible__c` | Picklist | `referral.metaInfo.azureDealRegIsEligible` → `Yes`/`No` (blank when unknown) | Whether the referral is eligible for Azure deal registration | | Microsoft External Reference ID | `AZURE_ExternalReferenceId__c` | Text | `externalReferenceId` | The external reference ID (CRM opportunity ID) sent to Microsoft Partner Center | | MS Managed Account ID | `AZURE_Managed_Account_Id__c` | Text (50) | `customerProfile.ids[]` entry with `profileType` = `External` | Microsoft's managed account ID for the customer. Set either by Fours' auto-connect before submission, or by Microsoft's server-side matching on inbound sync | #### GCP Fields **Basic Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | GCP Name | `GCP_Name__c` | Text | `name` | Resource name: `opportunities/{opportunity_id}` | | Opportunity Display Name | `GCP_OpportunityDisplayName__c` | Text | `opportunityInfo.displayName` | Display name for the Opportunity | | Identifier Number | `GCP_DealNumber__c` | Text | `qualificationInfo.dealNumber` | Identifier Number | | Description | `GCP_OpportunityDescription__c` | Long Text Area | `opportunityInfo.description` | Description | **Customer Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Customer Name | `GCP_CustomerName__c` | Text | `customerDisplayName` | Customer Name | | Partner Entered Company | `GCP_CustomerOrganizationName__c` | Text | `customerInfo.customerDetails.organizationName` | Partner Entered Company | | Customer Domain | `GCP_CustomerDomain__c` | Text | `customerInfo.customerDetails.domain` | Customer Domain | | Customer Project Number(s) | `GCP_CustomerProjectNumber__c` | Number | `partnerInfo.gcpProjectNumbers[0]` | Customer Project Number(s) | | Customer Project Number(s) | `GCP_CustomerProjectNumber_Text__c` | Text | `partnerInfo.gcpProjectNumbers`, comma-joined | Customer Project Number(s) as text | **Contact & Location:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | First Name | `GCP_ContactFamilyName__c` | Text | `customerInfo.contact.familyName` | First Name | | Last Name | `GCP_ContactGivenName__c` | Text | `customerInfo.contact.givenName` | Last Name | | Opportunity Team | `GCP_CustomerContacts__c` | Long Text Area | `customerContacts`, JSON-serialized | Opportunity Team | | Customer Contact Requested | `GCP_CustomerContactRequested__c` | Picklist | `customerContactRequested` → `Yes`/`No` | Customer Contact Requested | | Contact List | `GCP_TeamMembers__c` | Long Text Area | `opportunityTeamMembers`, JSON-serialized | Contact List | | Address Line 1 | `GCP_AddressLineOne__c` | Text | `customerInfo.customerDetails.address.addressLines[0]` | Address Line 1 | | Address Line 2 | `GCP_AddressLineTwo__c` | Text | `customerInfo.customerDetails.address.addressLines[1]` | Address Line 2 | | City | `GCP_Locality__c` | Text | `customerInfo.customerDetails.address.locality` | City | | State | `GCP_AdministrativeArea__c` | Text | `customerInfo.customerDetails.address.administrativeArea` | State | | Zip/Postal Code | `GCP_PostalCode__c` | Text | `customerInfo.customerDetails.address.postalCode` | Zip/Postal Code | | Partner Entered Country | `GCP_RegionCode__c` | Text | `customerInfo.customerDetails.address.regionCode` | Partner Entered Country | | Partner Entered Region | `GCP_Region__c` | Text | `customerInfo.region` | Partner Entered Region | **Deal Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Expected Revenue | `GCP_DealSize__c` | Currency | `qualificationInfo.dealSize.units` | Expected Revenue | | Opportunity Amount | `GCP_OpportunityAmount__c` | Currency | `opportunityInfo.opportunityAmount.units` | Opportunity Amount | | Budget | `GCP_Budget__c` | Text | `qualificationInfo.budget` | Budget | | Primary Campaign Source | `GCP_CampaignCode__c` | Text | `qualificationInfo.campaignCode` | Primary Campaign Source | | Partner Incentive Type | `GCP_IncentiveType__c` | Text | `partnerInfo.incentiveType` | Partner Incentive Type | | GCP Contract Vehicle | `GCP_ContractVehicle__c` | Picklist | `isvSolutionConnectInfo.contractVehicle` | GCP Contract Vehicle | | Contract Length (Months) | `GCP_ContractLengthMonths__c` | Number | `qualificationInfo.contractLengthMonths` | Contract Length (Months) | | Timeline | `GCP_Timeline__c` | Text | `qualificationInfo.timeline` | Timeline | | Authority | `GCP_Authority__c` | Text | `qualificationInfo.authority` | Authority | **Dates & Status:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Creation Date | `GCP_CreatedDate__c` | Date | `createTime` | Creation Date | | Created By | `GCP_CreatorEmail__c` | Email | `creatorEmail` | Created By | | Submitted Date | `GCP_SubmittedDate__c` | Date | `partnerInfo.submittedDate` (year/month/day) | Submitted Date | | Close Date | `GCP_EstimatedCloseDate__c` | Date | `qualificationInfo.estimatedCloseDate` (year/month/day) | Close Date | | Approved Date | `GCP_ApprovedDate__c` | Date | `partnerInfo.approvedDate` (year/month/day) | Approved Date | | Stage | `GCP_Stage__c` | Text | `stage` | Stage | | GCP Acceptance Status | `GCP_State__c` | Text | `state` | GCP Acceptance Status | | Decision Phase | `GCP_DecisionPhase__c` | Text | `qualificationInfo.decisionPhase` | Decision Phase | | GCP Opportunity Type | `GCP_OpportunityType__c` | Picklist | `opportunityType` | GCP Opportunity Type | | Opportunity Type | `GCP_OperationType__c` | Text | `qualificationInfo.operationType` | Opportunity Type | | Opportunity Owner | `GCP_Owner__c` | Text | `owner` | Opportunity Owner | | Opportunity Owner Email | `GCP_OwnerEmail__c` | Email | `ownerEmail` | Opportunity Owner Email | **Products & Services:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Products | `GCP_Products__c` | Long Text Area | `opportunityLines`, JSON-serialized | Products | | Product Category | `GCP_ProductCategory__c` | Text | `opportunityInfo.productCategory`, `;`-joined | Product Category | | Product Family | `GCP_ProductFamily__c` | Text | `opportunityInfo.productFamily`, `;`-joined | Product Family | | Need | `GCP_Need__c` | Text | `qualificationInfo.need` | Need | **Classifications & Attributes:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Industry | `GCP_Industry__c` | Text | `customerInfo.customerDetails.industry` | Industry | | Number of Employees | `GCP_EmployeeCount__c` | Number | `customerInfo.customerDetails.employeeCount` | Number of Employees | | GCP Delivery Model | `GCP_DeliveryModel__c` | Picklist | `isvSolutionConnectInfo.deliveryModel` | GCP Delivery Model | | Support Level | `GCP_SupportLevel__c` | Picklist | `isvSolutionConnectInfo.supportLevel` | Support Level | | Distributor | `GCP_Distributor__c` | Text | `partnerInfo.distributor` | Distributor | | Billing Subaccount ID | `GCP_SubbillingAccountId__c` | Text | `partnerInfo.subBillingAccountId` | Billing Subaccount ID | | Confidential | `GCP_Confidential__c` | Picklist | `opportunityInfo.confidential` → `Yes`/`No` | Confidential | | Is ISV Solution Connect Deal | `GCP_IsvSolutionConnectDeal__c` | Picklist | presence of `isvSolutionConnectInfo` → `Yes`/`No` | Is ISV Solution Connect Deal | | MSSP Deal | `GCP_MsspDeal__c` | Picklist | `qualificationInfo.msspDeal` → `Yes`/`No` | MSSP Deal | | Legal Language Accepted | `GCP_LegalLanguageAccepted__c` | Picklist | `qualificationInfo.legalLanguageAccepted` → `Yes`/`No` | Legal Language Accepted | | Partner Ready to Close | `GCP_PartnerReadyToClose__c` | Picklist | `salesCycle.partnerReadyToClose` | Partner Ready to Close | | Opportunity Source | `GCP_Source__c` | Text | `source` (Google vs Partner originated) | Opportunity Source | **Extensions & Rebates:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Number of Extensions | `GCP_ExtensionsCount__c` | Number | `partnerInfo.extensionsCount` | Number of Extensions | | Close Date Push Count | `GCP_CloseDatePushCount__c` | Number | `salesCycle.closeDatePushCount` | Close Date Push Count | | Rebate Expiration Date | `GCP_RebateExpirationDate__c` | Date | `partnerInfo.rebateExpirationDate` (year/month/day) | Rebate Expiration Date | | Rebate extension | `GCP_RebateExtension__c` | Long Text Area | `rebateExtensions`, JSON-serialized | Rebate extension | **Win/Loss Information:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Win Main Reason | `GCP_WinMainReason__c` | Text Area | `winLossInfo.winMainReason` | Win Main Reason | | Won Reason | `GCP_WonReason__c` | Text Area | `winLossInfo.wonReason` | Won Reason | | Loss Main Reason | `GCP_LostMainReason__c` | Text Area | `winLossInfo.lostMainReason` | Loss Main Reason | | Lost Reason | `GCP_LostReason__c` | Text | `winLossInfo.lostReason` | Lost Reason | | Lost/rejected Reason | `GCP_LostRejectedReasonDetails__c` | Text Area | `winLossInfo.lostRejectedReasonDetails` | Lost/rejected Reason | | Win/Loss Products | `GCP_WinLossProducts__c` | Text | `winLossInfo.winLossProducts`, `;`-joined | Win/Loss Products | | Win/Loss Context | `GCP_WinLossAdditionalContext__c` | Text Area | `winLossInfo.winLossAdditionalContext` | Win/Loss Context | **Additional Fields:** | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | PRM Site Details | `GCP_PrmSiteDetails__c` | Text | `salesCycle.prmSiteDetails` | PRM Site Details | #### PRM (Fours Co-Sell) Fields Populated for co-sell referrals shared through Fours PRM — partner-to-partner (org-to-org) co-sells. Only the minimal important deal information is synced; commission / revenue-share terms are intentionally not exposed. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | PRM Partner ID | `PRM_Partner_ID__c` | Text (External ID) | `referral.partnerId` | Fours partnership ID this referral belongs to | | PRM Partner Name | `PRM_Partner_Name__c` | Text | partnership name resolved from `referral.partnerId` | Partner organization name | | PRM Type | `PRM_Type__c` | Text | `type` | Opportunity type (New Business, Renewal, Expansion, Add On) | | PRM Deal Role | `PRM_DealRole__c` | Text | `dealRole` | This org's role on the deal (Seller / Referrer) | | PRM Customer Company Name | `PRM_CustomerCompanyName__c` | Text | `customerInfo.companyName` | End-customer company name | | PRM Customer Domain | `PRM_CustomerDomain__c` | Text | `customerInfo.website` | End-customer domain / website | | PRM Customer Industry | `PRM_CustomerIndustry__c` | Text | `customerInfo.industry` | End-customer industry | | PRM Customer Country | `PRM_CustomerCountry__c` | Text | `customerInfo.country` | End-customer country | | PRM Customer Business Problem | `PRM_CustomerBusinessProblem__c` | Long Text Area | `dealDetails.customerBusinessProblem` | Customer business problem | | PRM Use Case | `PRM_UseCase__c` | Long Text Area | `dealDetails.useCase` | Use case | | PRM Target Close Date | `PRM_TargetCloseDate__c` | Date | `dealDetails.targetCloseDate` | Target close date | | PRM Deal Value | `PRM_DealValue__c` | Number | `dealDetails.dealValueAmount` | Deal value amount | | PRM Deal Value Currency | `PRM_DealValueCurrency__c` | Text | `dealDetails.dealValueCurrency` | Deal value currency (ISO 4217) | | PRM Stage | `PRM_Stage__c` | Text | `stage` | Deal lifecycle stage | | PRM Status | `PRM_Status__c` | Text | `status` | Sharing status of this copy | | PRM Delivery Model | `PRM_DeliveryModel__c` | Text | `dealDetails.deliveryModel`, `;`-joined | Delivery model(s) | | PRM Next Steps | `PRM_NextSteps__c` | Long Text Area | `nextSteps` | Next steps | | PRM Created Date | `PRM_CreatedDate__c` | Date/Time | `createdDateTime` | Created date | | PRM Accepted Date | `PRM_AcceptedDate__c` | Date/Time | `acceptedDateTime` | Accepted date | --- ### Contact__c Stores partner contacts (e.g., AWS PDM, Azure PM, GCP PSO) associated with referrals and accounts. Used in co-sell flows to identify the partner-side person managing a deal. The accounts and opportunities a contact covers are held here as JSON (`Accounts__c`, `Opportunities__c`), which a report cannot filter, group, or join. To report on them, use [Contact_Account__c](#contact_account__c) and [Contact_Opportunity__c](#contact_opportunity__c) below. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Contact ID | `Contact_ID__c` | Text (External ID) | — legacy, superseded by `Contact_ID_CS__c` | Fours Contact ID — legacy identifier for the partner contact. Kept for existing records and no longer written on sync, so it is empty on contacts synced from now on. Use `Contact_ID_CS__c` to identify a contact. | | Contact ID (Case-Sensitive) | `Contact_ID_CS__c` | Text (External ID), **required**, **case-sensitive unique** | `contact.id` | Fours Contact ID — the identifier Fours matches contacts on. Case-sensitive uniqueness means two IDs differing only in letter case are two different contacts, which is what makes it a safe upsert key. Being required, it must carry a value on any Contact record you create or load by hand; `Contact_ID__c` is optional. | | Partner | `Partner__c` | Text | `contact.info.partner` | Cloud partner associated with this contact (AWS, AZURE, GCP). | | Role | `Role__c` | Text | `contact.info.role` | Role of the partner contact (e.g., AWS PDM, Azure PM, GCP PSO). | | Source | `Source__c` | Picklist | contact metrics — source system | Source of the contact — `Referral` (came in via a referral) or `Predicted` (inferred). | | Email | `Email__c` | Email | `contact.emailAddress` | Email address of the partner contact. | | Phone | `Phone__c` | Phone | `contact.info.phoneNumber` | Phone number of the partner contact. | | Tags | `Tags__c` | Long Text Area | `contact.tags` (comma-joined) | Comma-separated tags for the contact (e.g., `partner`, `cosell`, `aws`). | | Industries | `Industries__c` | Long Text Area | contact metrics — industries (comma-joined) | Comma-separated list of industries covered by this contact. | | Managed Domains | `Managed_Domains__c` | Long Text Area | contact metrics — managed domains (comma-joined) | Comma-separated list of customer domains managed by this contact. | | Managed Regions | `Managed_Regions__c` | Long Text Area | contact metrics — distinct account regions (comma-joined) | Comma-separated list of regions managed by this contact. | | Accounts | `Accounts__c` | Long Text Area | contact metrics — accounts (JSON) | JSON array of accounts associated with this contact. | | Opportunities | `Opportunities__c` | Long Text Area | contact metrics — opportunities (JSON) | JSON array of opportunities associated with this contact. | | Account Count | `Account_Count__c` | Number | contact metrics — account count | Total number of accounts managed by this contact. | | Active Opportunity Count | `Active_Opportunity_Count__c` | Number | contact metrics — active opportunity count | Number of active opportunities associated with this contact. | | Referral Count | `Referral_Count__c` | Number | contact metrics — referral count | Total number of referrals associated with this contact. | | Pipeline | `Pipeline__c` | Currency | contact metrics — USD pipeline | Total open pipeline value for this contact. | | Success Rate | `Success_Rate__c` | Percent | contact metrics — success rate | Success rate percentage for referrals brought by this contact. | | Info | `Info__c` | Long Text Area | `contact.info` (full JSON) | Full contact info JSON from Fours. | | Creation Date | `Creation_Date__c` | Date | `contact.creationTime` | Date when the contact was created in Fours. | | Last Update Date | `Last_Update_Date__c` | Date | `contact.lastUpdateTime` | Date when the contact was last updated in Fours. | --- ### Contact_Account__c **Partner Contact Account (Suger)** — one row per partner contact and Salesforce **Account** that Fours has mapped together, including accounts with no open opportunities. It is the reportable form of a contact's account list: build reports on it with the [partner-contact report types](/salesforce-app/salesforce-app-reports/#partner-contact-report-types). Row names are numbered automatically (`CA-000001`, `CA-000002`, …). | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Partner Contact (Suger) | `Contact__c` | Master-Detail (`Contact__c`) | the contact's `Suger__Contact__c` record | The partner contact the row belongs to. Sharing follows the contact, and deleting the contact deletes its rows | | Account | `Account__c` | Lookup (Account) | the Account ID in the contact's mapping | The Salesforce Account the contact is mapped to. Deleting the Account clears this field and leaves the row in place | | Association Key (Case-Sensitive) | `Association_Key_CS__c` | Text (External ID), **required**, **case-sensitive unique** | `:<15-character Account ID>` | The key Fours matches rows on — one row per contact and Account | | Suger Contact ID | `Suger_Contact_ID__c` | Text (External ID) | `contact.id` | Fours' own contact ID, for joining back to Fours from a data warehouse. Not unique: one contact has many rows | | Contact Name | `Contact_Name__c` | Text | `contact.name` | Copied from the contact, so it can sit beside Account columns in a report | | Contact Email | `Contact_Email__c` | Email | `contact.emailAddress` | Copied from the contact. Left empty when the address is not a valid email | | Contact Role | `Contact_Role__c` | Text (128) | `contact.info.role` | The contact's role as Fours holds it — for example sales rep, partner development manager, or ISV success manager | | Partner | `Partner__c` | Picklist | `contact.info.partner` | The contact's cloud partner: `AWS`, `AZURE`, `GCP`, or `SUGER` | | Link Source | `Source__c` | Picklist | how the contact came to be mapped to the Account | `Referral`, `Predicted`, or `Upload` — see [How a row's Link Source is set](#how-a-rows-link-source-is-set) | | Last Referral Time | `Last_Referral_Time__c` | DateTime | the mapping's most recent referral | The most recent referral this contact took part in for the Account. Empty on `Predicted` rows | | Collaboration Score | `Collaboration_Score__c` | Number | the contact's collaboration score for this Account, rounded to a whole number | Fours' 0–100 collaboration score for this contact on this Account, recalculated nightly. Blank until Fours has scored the pair | | Last Seen | `Last_Seen__c` | DateTime | the time of the backfill run that last confirmed the row | Updated whenever Fours confirms the association still exists — at least once a week | --- ### Contact_Opportunity__c **Partner Contact Opportunity (Suger)** — one row per partner contact and Salesforce **Opportunity**. A contact is associated with every opportunity on each Account it is mapped to, so an Account with three mapped contacts and four opportunities produces twelve rows. Row names are numbered `CO-000001`, `CO-000002`, and so on. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Partner Contact (Suger) | `Contact__c` | Master-Detail (`Contact__c`) | the contact's `Suger__Contact__c` record | The partner contact the row belongs to. Sharing follows the contact, and deleting the contact deletes its rows | | Opportunity | `Opportunity__c` | Lookup (Opportunity) | an opportunity on one of the contact's mapped Accounts | The Salesforce Opportunity. Deleting the Opportunity clears this field and leaves the row in place | | Association Key (Case-Sensitive) | `Association_Key_CS__c` | Text (External ID), **required**, **case-sensitive unique** | `:<15-character Opportunity ID>` | The key Fours matches rows on — one row per contact and Opportunity | | Suger Contact ID | `Suger_Contact_ID__c` | Text (External ID) | `contact.id` | Fours' own contact ID. Not unique | | Contact Name | `Contact_Name__c` | Text | `contact.name` | Copied from the contact | | Contact Email | `Contact_Email__c` | Email | `contact.emailAddress` | Copied from the contact. Left empty when the address is not a valid email | | Contact Role | `Contact_Role__c` | Text (128) | `contact.info.role` | The contact's role as Fours holds it | | Partner | `Partner__c` | Picklist | `contact.info.partner` | `AWS`, `AZURE`, `GCP`, or `SUGER` | | Link Source | `Source__c` | Picklist | the contact's mapping to the Opportunity's Account | `Referral`, `Predicted`, or `Upload` | | Last Referral Time | `Last_Referral_Time__c` | DateTime | the contact's mapping to the Opportunity's Account | The most recent referral this contact took part in for that Account. Empty on `Predicted` rows | | Last Seen | `Last_Seen__c` | DateTime | the time of the backfill run that last confirmed the row | Updated whenever Fours confirms the association still exists — at least once a week | Stage, amount, close date, and the rest of the Opportunity are not copied onto the row — a report reaches them through the Opportunity itself. Collaboration Score exists only on `Contact_Account__c`. ```d2 direction: right contact: "Partner contact\nContact__c" mapA: "Mapped to Account A\nwith Opportunities 1 and 2" mapB: "Mapped to Account B\nno opportunities" rowA: "Contact_Account__c\nrow for Account A" rowB: "Contact_Account__c\nrow for Account B" opp1: "Contact_Opportunity__c\nrow for Opportunity 1" opp2: "Contact_Opportunity__c\nrow for Opportunity 2" contact -> mapA contact -> mapB mapA -> rowA mapA -> opp1 mapA -> opp2 mapB -> rowB ``` #### How a row's Link Source is set | Link Source | What it means | | ----------- | ------------- | | `Referral` | The contact took part in actual referral activity for the Account. | | `Predicted` | Fours matched the contact to the Account by email domain. The link is inferred, not confirmed. | | `Upload` | An admin created the mapping by uploading a CSV file. | The value only ever moves up — `Predicted`, then `Upload`, then `Referral` — so it describes where the association stands now, not how it started. Group or filter on it to keep confirmed referral activity apart from inferred matches. #### When rows appear, change, and go away - Fours writes both objects during the Salesforce backfill of **partner contacts**, straight after the contacts themselves. The backfill runs only while the **Contact** object's **Sync** is on in [Choose What Backfills to Salesforce](/integrations/salesforce/#choose-what-backfills-to-salesforce), and it covers every partner contact on each run — the **Days Back** setting does not narrow it. - A row is added when an association appears and removed on a later run when the association no longer exists. A row whose contact is no longer a partner contact is removed once 30 days pass without Fours confirming it — which is what **Last Seen** records. - Deleting an Account or Opportunity in Salesforce clears the lookup on its rows instead of deleting them, so such a row can show in a report with a blank **Account** or **Opportunity**. - Both objects ship with the managed package. On a package version that does not include them, Fours skips them and the rest of the contact backfill carries on — [upgrade the package](/salesforce-app/salesforce-app-install/) to get them. **Access.** Every Fours user, co-sell, marketplace, and funding permission set grants **read-only** access to both objects, including their **Account** and **Opportunity** fields. Only **Suger Integrator** and **Suger Integrator (Salesforce Integration License)** can create, edit, or delete rows. The approval and Finance Operation add-ons grant nothing here. --- ### Lead__c Represents AWS lead invitations and the leads they convert into. Written only for the **AWS** partner — Azure and GCP have no equivalent lead object. Salesforce shows the object as **Lead (Suger)** / **Leads (Suger)**, keeping it distinct from the standard Salesforce Lead object. To work these records in the app rather than report on them, see [Work AWS Co-Sell Leads](/salesforce-app/salesforce-app-leads/) — the **Leads V2 (Suger)** tab reads live from Fours, so it can differ from the backfilled fields below between sync runs. :::info Field Population Timing Leads populate in two waves, the same way AWS engagement invitations do: **Before you accept**, only the invitation payload is available. It is **masked and carries no PII** — company and market attributes populate, but customer name, email and phone stay empty. **After you accept**, AWS shares the full lead context, and the customer contact fields (`Customer_First_Name__c`, `Customer_Last_Name__c`, `Customer_Email__c`, `Customer_Phone__c`), interactions and the readiness score fill in. ::: | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Lead ID | `Lead_ID__c` | Text (External ID) | `lead.id` | The unique ID of the Lead in Fours | | Partner | `Partner__c` | Picklist | `lead.partner` (always `AWS`) | The cloud partner that sent the lead | | External ID | `External_Id__c` | Text | `lead.externalId` | The lead's ID in AWS Partner Central | | Invitation ID | `Invitation_Id__c` | Text | `lead.invitationId` | The AWS engagement invitation that carried this lead | | Context ID | `Context_Id__c` | Text | `lead.contextId` | The AWS lead context ID, available after acceptance | | Invitation Status | `Invitation_Status__c` | Text | `lead.invitationStatus` | Invitation status (`PENDING`, `ACCEPTED`, `REJECTED`, `EXPIRED`) | | Status | `Status__c` | Text | `lead.status` | The lead's status in Fours | | Qualification Status | `Qualification_Status__c` | Text | invitation `qualificationStatus`, overridden post-accept by the lead context | How AWS has qualified the lead | | Readiness Score | `Readiness_Score__c` | Text (50) | **Post-accept only** — `insights.leadReadinessScore` | AWS's readiness score for the lead | | Company Name | `Company_Name__c` | Text | `customer.companyName` | The prospect's company name | | Industry | `Industry__c` | Text | `customer.industry` | The prospect's industry | | Market Segment | `Market_Segment__c` | Text | `customer.marketSegment` | The prospect's market segment | | AWS Maturity | `Aws_Maturity__c` | Text | `customer.awsMaturity` | How far along the prospect is with AWS | | Website | `Website__c` | Text | `customer.websiteUrl` | The prospect's website | | City | `City__c` | Text | **Post-accept only** — `customer.address.city` | City | | State | `State__c` | Text | **Post-accept only** — `customer.address.stateOrRegion` | State or region | | Postal Code | `Postal_Code__c` | Text (40) | **Post-accept only** — `customer.address.postalCode` | Postal code | | Country | `Country__c` | Text | `customer.address.countryCode`, expanded to the full country name | Country | | Customer First Name | `Customer_First_Name__c` | Text | **Post-accept only** — `interactions[0].contact.firstName` | Contact first name. Empty before acceptance — the invitation payload is masked | | Customer Last Name | `Customer_Last_Name__c` | Text | **Post-accept only** — `interactions[0].contact.lastName` | Contact last name | | Customer Email | `Customer_Email__c` | Email | **Post-accept only** — `interactions[0].contact.email` | Contact email | | Customer Phone | `Customer_Phone__c` | Phone | **Post-accept only** — `interactions[0].contact.phone` | Contact phone | | Customer Title | `Customer_Title__c` | Text | `interactions[0].contact.businessTitle` (invitation: `interaction.contactBusinessTitle`) | Contact business title | | Interactions | `Interactions__c` | Long Text Area | `interactions`, JSON-serialized | The lead's interaction history as a JSON array | | Converted Opportunity ID | `Converted_Opportunity_Id__c` | Text | `lead.convertedOpportunityId` | The AWS opportunity this lead converted into | | Converted Referral | `Converted_Referral__c` | Lookup | the `Suger__Referral__c` record for the converted referral | Left unset until that referral itself reaches Salesforce; filled on a later backfill run | | Account ID | `AccountID__c` | Lookup | `lead.salesforceAccountId` | Reference to Salesforce Account | | Opportunity ID | `OpportunityID__c` | Lookup | `lead.salesforceOpportunityId` | Reference to Salesforce Opportunity | | Expiration Date | `Expiration_Date__c` | Date | — not populated by sync | Expiration Date | --- ### Referral_Bulk_Share_Job__c Tracks the status of bulk referral share jobs (e.g., sharing many referrals to a cloud partner in one operation). Used by the admin UI to monitor progress and surface failures. | Label | API Name | Type | Description | | ----- | -------- | ---- | ----------- | | Job ID | `Referral_Bulk_Share_Job_ID__c` | Text (External ID) | Unique identifier for the bulk share job. | | Partner | `Partner__c` | Picklist | Cloud partner the job is sharing referrals to (AWS, AZURE, GCP). | | State | `State__c` | Picklist | Current job state (e.g., Running, Succeeded, Failed). | | Total Count | `Total_Count__c` | Number | Total number of referrals queued in the job. | | Succeeded Count | `Succeeded_Count__c` | Number | Number of referrals successfully shared. | | Failed Count | `Failed_Count__c` | Number | Number of referrals that failed to share. | | Start Date | `Start_Date__c` | DateTime | When the job started executing. | | Finish Date | `Finish_Date__c` | DateTime | When the job completed (success or failure). | | Created Date | `Created_Date__c` | DateTime | When the job was first queued. | | Error Message | `Error_Message__c` | Long Text Area | Aggregated error message describing why the job failed (if applicable). | | Details | `Details__c` | Long Text Area | Per-referral details including individual success/failure reasons. | --- ## Funding Objects ### Funding__c Tracks funding programs and cash/credit requests from cloud marketplace partners. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Funding Application ID | `FundingApplicationId__c` | Text | `fundingApplication.id` | The unique ID of the Funding Application | | Partner | `Partner__c` | Picklist | `fundingApplication.partner` | Partner (AWS/AZURE/GCP) | | Referral | `Referral__c` | Lookup | the one AWS referral on this record's Opportunity (15- and 18-character IDs match); set only when that Opportunity has exactly one AWS referral — otherwise Fours leaves the field out of the sync, so a new record stays empty and an existing value is kept | Reference to Referral | | Opportunity | `Opportunity__c` | Lookup | the Opportunity the funding request was created from or linked to in Fours; left empty if Salesforce no longer has it | Reference to Salesforce Opportunity | | Approval Status | `Approval_Status__c` | Picklist | the funding application's approval status | Where the request stands in your organization's funding approval: `Not Submitted`, `Submitted`, `Approved`, `Declined`, or `Action Required` | | AWS Activity Name | `AWS_ActivityName__c` | Text | **AWS only** — benefit application activity name | AWS Activity Name | | AWS Annual Run Rate | `AWS_AnnualRunRate__c` | Currency | **AWS only** — benefit application annual run rate, including ISV Workload Migration requests | AWS Annual Run Rate | | AWS Benefit Application Id | `AWS_BenefitApplicationId__c` | Text | **AWS only** — benefit application ID | AWS Benefit Application Id | | AWS Funding Program | `AWS_FundingProgram__c` | Text | **AWS only** — benefit application programs (`;`-joined) | AWS Funding Program | | AWS Funding Request Status | `AWS_FundingRequestStatus__c` | Picklist | **AWS only** — benefit application status | AWS Funding Request Status | | AWS Planned Start Date | `AWS_PlannedStartDate__c` | Date | **AWS only** — benefit application planned start date | AWS Planned Start Date | | AWS Planned End Date | `AWS_PlannedEndDate__c` | Date | **AWS only** — benefit application planned end date | AWS Planned End Date | | AWS Cash Request Requested Amount | `AWS_CashRequest_RequestedAmount__c` | Currency | **AWS only** — cash request requested amount | AWS Cash Request Requested Amount | | AWS Cash Request Approved Amount | `AWS_CashRequest_ApprovedAmount__c` | Currency | **AWS only** — cash request approved amount | AWS Cash Request Approved Amount | | AWS Cash Request Total Cost Of Activity | `AWS_CashRequest_TotalCostOfActivity__c` | Currency | **AWS only** — cash request total activity cost | AWS Cash Request Total Cost Of Activity | | AWS Cash Request Purchase Order Number | `AWS_CashRequest_PurchaseOrderNumber__c` | Text | **AWS only** — cash request purchase order number | The purchase order number AWS issued for the cash request | | AWS Cash Request Account Profile ID | `AWS_CashRequest_AccountProfileId__c` | Text | **AWS only** — cash request account profile ID | The Payee Central account profile the cash is paid to | | AWS Partner Contact Email | `AWS_PartnerContactEmail__c` | Long Text Area | **AWS only** — partner contacts' emails (`;`-joined) | Your contacts on the request | | AWS Account ID | `AWS_AwsAccountId__c` | Text | **AWS only** — the AWS account on the request | AWS Account ID | | AWS ACE Opportunity ID | `AWS_AceOpportunityId__c` | Text | **AWS only** — the ACE opportunity the request is associated with | AWS ACE Opportunity ID | | AWS Fulfillment Types | `AWS_FulfillmentTypes__c` | Text | **AWS only** — fulfillment types (`;`-joined): `CREDITS`, `CASH`, `DISCOUNT`, `ACCESS`, `RECOGNITION`, `RESOURCE` | How the funding is fulfilled | | AWS Issued Amount | `AWS_IssuedAmount__c` | Currency | **AWS only** — the allocation's issued amount | The amount AWS issued (for example, credits issued) | | AWS Expiration Date | `AWS_ExpirationDate__c` | Date | **AWS only** — the ISV Workload Migration expiry, otherwise the allocation's | When the funding expires | | AWS ISV WMP Second Tranche Consent | `AWS_IsvWmpSecondTrancheConsentCaptured__c` | Text | **AWS only** — ISV Workload Migration second-tranche consent | The second-tranche consent value, as AWS reports it | | Credit Requested Amount | `Credit_Requested_Amount__c` | Currency | credit request requested amount | Credit Requested Amount | | Credit Approved Amount | `Credit_Approved_Amount__c` | Currency | credit request approved amount | Credit Approved Amount | | Credit Currency | `Credit_Currency__c` | Text | credit request currency | Credit Currency | | Credit Number Of Codes | `Credit_Number_Of_Codes__c` | Number | credit request number of codes | Credit Number Of Codes | | Credit Codes | `Credit_Codes__c` | Long Text Area | credit codes (newline-joined) | Issued AWS credit codes (one per line) | --- ### FundingCashClaim__c Tracks individual cash claims against funding requests. | Label | API Name | Type | Populated From | Description | | ----- | -------- | ---- | -------------- | ----------- | | Funding Request | `Funding_Request__c` | Lookup | parent `Suger__Funding__c` record | Reference to parent Funding | | Claim Amount | `Claim_Amount__c` | Currency | cash claim amount | Claim Amount | | Claim Status | `Claim_Status__c` | Text | benefit application status | Claim Status | | AWS Benefit Application Id | `AWS_BenefitApplicationId__c` | Text | the claim's benefit application ID | The fund claim ID (`benappl-…`) | | Claim Start Date | `Claim_Start_Date__c` | Date | the claim's start date, once AWS records it | Claim period start | | Claim End Date | `Claim_End_Date__c` | Date | the claim's end date, once AWS records it | Claim period end | | Claim Due Date | `Claim_Due_Date__c` | Date | the claim's due date, once AWS records it | When claim is due | --- ## Configuration Objects These objects store app-wide configuration that affects how the Fours Salesforce App behaves. They are typically managed by administrators, not end users. ### Suger_Organization__c Stores the connection between the Fours Salesforce App and the Fours backend (API credentials, OAuth client info, organization-level feature toggles). | Label | API Name | Type | Description | | ----- | -------- | ---- | ----------- | | Organization ID | `Organization_Id__c` | Text | Fours organization ID this Salesforce org is connected to. | | API Endpoint | `Api_Endpoint__c` | URL | Fours API base URL (typically `https://api.suger.cloud`). | | API Key | `Api_Key__c` | Text | API key for Fours API access. Stored encrypted. | | AES Key | `Aes_Key__c` | Text | Crypto AES key used to encrypt the API key at rest. | | OAuth Client ID | `OAuth_Client_Id__c` | Text | OAuth app `client_id` used for the OAuth 2.0 client-credentials flow when API-key auth is not used. | | OAuth Client Secret | `OAuth_Client_Secret__c` | Text | OAuth app `client_secret` for the client-credentials flow. Stored encrypted. | | Enable Approval Process | `Enable_Approval_Process__c` | Checkbox | When on, Fours uses Salesforce's native Approval Process for offer/referral approvals. | | Enable Offer Set In Opportunity Level | `Enable_Offer_Set_In_Opportunity_Level__c` | Checkbox | When on, multiple offers can be associated with one Opportunity via `Opportunity_Offer__c`. | | Enable Product Filter | `Enable_Product_Filter__c` | Checkbox | When on, the Create Offer UI restricts product selection using `Product_Filter__c`. | | Product Filter | `Product_Filter__c` | Text | Filter expression that limits which products appear in the Create Offer dropdown. | | Tab Settings | `Tab_Settings__c` | Text | JSON object storing per-tab visibility. Tabs not listed (or set to `false`) are enabled by default. | | Enable Widget Pin Lock | `Enable_Widget_Pin_Lock__c` | Checkbox | When on, the Opportunity widget Pinned sections are enforced org-wide and users can no longer pin/unpin their own sections. | | Widget Pinned Sections | `Widget_Pinned_Sections__c` | Text | JSON array of section keys pinned org-wide when the pin lock is on (max 2), e.g. `["offer","funding"]`. | | Offer Triggering Record Field Set Name | `Offer_Triggering_Record_Field_Set_Name__c` | Text | API name of a Salesforce Field Set that controls which fields appear when creating the triggering record (e.g., Opportunity) from the Create Offer flow. | | Additional Offer Triggering Relationship | `Additional_Offer_Triggering_Relationship__c` | Text | A relationship from Opportunity used as an additional input for field mapping during offer creation. | --- ### View__c Stores user-saved list view configurations (column choices, filters, sort order) for Fours object pages in the Console. Allows admins to create reusable, shareable views. | Label | API Name | Type | Description | | ----- | -------- | ---- | ----------- | | Name | `Name__c` | Text | Display name of the saved view. | | Target Context | `Target_Context__c` | Text | The Fours object/page this view applies to (e.g., `Account`, `Offer`, `Referral`). | | Columns | `Columns__c` | Long Text Area | JSON representation of the column configuration (which columns to show, in what order). | | Filter Logic | `Filter_Logic__c` | Long Text Area | JSON representation of the active filter conditions. | | Sort Logic | `Sort_Logic__c` | Long Text Area | JSON representation of the active sort configuration. | | Metadata | `Metadata__c` | Long Text Area | JSON representation of view metadata (e.g., `disableActions`, other UI flags). | | Permission Sets | `Permission_Sets__c` | Long Text Area | Comma-separated list of permission set names that can see this view. Empty means owner-only. | --- ## Custom Metadata Types ### Referral_Lookup_Filter__mdt Configurable lookup filters for the Referral object. Allows admins to define filter criteria for Opportunity and Account lookups on referral records. | Label | API Name | Type | Description | | ----- | -------- | ---- | ----------- | | Label | `MasterLabel` | Text | Display name for this filter | | Developer Name | `DeveloperName` | Text | API name for this filter | | Object Name | `Object_Name__c` | Text | Target object: `Opportunity` or `Account` | | Filter Condition | `Filter_Condition__c` | Long Text Area | SOQL-like filter expression | | Display Field Set | `Display_Field_Set__c` | Text | Optional. API name of a field set on the target object; the first field (excluding `Name` and `Id`) is shown as extra info in the picker suggestions | | Search Field | `Search_Field__c` | Text | Optional. API name of one additional field to match against the search text, e.g. `Opportunity_Number__c`. The `Name` field is always searched. Only text and text-formula fields are supported | | Is Active | `Is_Active__c` | Checkbox | Enable/disable the filter | #### How to Configure 1. Click the **Gear Icon (⚙️) > Setup**. 2. In the **Quick Find** box, type `Custom Metadata Types`. 3. Locate the row labeled **Referral Lookup Filter** (Namespace Prefix: SUGER) and click **Manage Records**. 4. Click **New** to create a new filter rule. 5. Fill in the fields and click **Save**. #### Filter Condition Syntax The `Filter_Condition__c` field accepts SOQL-like filter expressions with these features: **Supported Operators:** | Operator | Example | Description | | -------- | ------- | ----------- | | `=` | `Status = 'Active'` | Equals | | `!=` or `<>` | `Type != 'Archived'` | Not equals | | `<` | `Amount < 1000` | Less than | | `>` | `Amount > 500` | Greater than | | `<=` | `Count <= 10` | Less than or equal | | `>=` | `Count >= 5` | Greater than or equal | | `LIKE` | `Name LIKE '%Corp%'` | Pattern matching | | `IN` | `Type IN ('A', 'B', 'C')` | Match any value in list | | `NOT IN` | `Stage NOT IN ('Lost', 'Won')` | Exclude values in list | **Logical Operators:** - `AND` - Both conditions must be true - `OR` - Either condition must be true - `()` - Parentheses for grouping (supports nesting) **Value Types:** | Type | Example | | ---- | ------- | | String | `'Active'` or `"Active"` | | Boolean | `true` or `false` | | Number | `100`, `99.5` | | Null | `null` | | Empty String | `''` | **Dynamic Field References:** Reference values from the Referral record using `{ObjectName__c.FieldName__c}` syntax: ```text Name = {Referral__c.AWS_CustomerCompanyName__c} Suger__Hyperscaler__c = {Referral__c.Partner__c} ``` Relationship fields are also supported: ```text Account.Name = {Referral__c.Account__r.Name} ``` #### Example Filter Conditions **Filter Opportunities by Stage:** ```text StageName NOT IN ('Closed Lost', 'Closed Won') ``` **Filter by Amount and Type:** ```text Amount > 10000 AND Type IN ('New Business', 'Expansion') ``` **Complex Filter with Dynamic References:** ```text Type IN ('1P', 'Standard') AND StageName NOT IN ('Closed Lost', 'Closed Won') AND Suger__CosellShared__c = false AND (Suger__Hyperscaler__c = {Referral__c.Partner__c} OR Suger__Hyperscaler__c = '' OR Suger__Hyperscaler__c = null) ``` :::tip Multiple filter records for the same object are combined with `AND`. Create separate records to organize complex filter logic. ::: #### Searching by an Additional Field By default, the record picker in the referral **Link Opportunity** / **Link Account** dialogs matches your search text against the record `Name` only. To also search by another field — for example an opportunity number like `OPP-002370084` — set **Search Field** (`Search_Field__c`) to that field's API name: | Field | Value | | ----- | ----- | | Object Name | `Opportunity` | | Search Field | `Opportunity_Number__c` | | Is Active | ✓ | With this record active, typing either an opportunity name or an opportunity number in the picker finds the record, and the configured field is shown next to each suggestion. :::note The record picker supports only one additional search field per object, and only text and text-formula fields. If your field is an Auto Number field and search does not match it, create a text formula field that mirrors it and configure that formula field instead. ::: :::warning Filter conditions are validated at runtime. Invalid field names or syntax errors will cause the lookup to fail. Test your filters thoroughly before activating them. ::: ### Entitlement_Lookup_Filter__mdt and Offer_Lookup_Filter__mdt Configurable filters for the Opportunity picker behind **Link** on an entitlement's or an offer's Opportunity panel in the Salesforce app. Each type applies only to its own picker, independently of the referral filters above: an **Entitlement Lookup Filter** record shapes the entitlement picker, an **Offer Lookup Filter** record the offer picker. | Label | API Name | Type | Description | | ----- | -------- | ---- | ----------- | | Label | `MasterLabel` | Text | Display name for this filter | | Developer Name | `DeveloperName` | Text | API name for this filter | | Object Name | `Object_Name__c` | Picklist | `Opportunity` — the only object these pickers look up | | Filter Condition | `Filter_Condition__c` | Long Text Area | SOQL-like filter expression, as for referrals. A condition that references another record with `{Object.Field}` is skipped by these pickers | | Display Field Set | `Display_Field_Set__c` | Text | Not read by these pickers | | Search Field | `Search_Field__c` | Text | Optional. One additional text or text-formula field to match against the search text, as described in [Searching by an Additional Field](#searching-by-an-additional-field). `Name` is always searched | | Is Active | `Is_Active__c` | Checkbox | Enable/disable the filter | Create the records the same way as a referral filter — **Setup** → **Custom Metadata Types** → **Manage Records** — choosing **Entitlement Lookup Filter** or **Offer Lookup Filter**. Without an active record, the picker lists every Opportunity you can see and matches your search text against `Name` only. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-custom-permissions/ # Custom Permissions This guide documents all custom permissions in the Fours Salesforce App. Custom permissions control feature access and UI visibility for offers, referrals, and administrative functions. ## Overview Fours uses Salesforce Custom Permissions to control granular access to specific features within the app. These permissions are assigned to users through Permission Sets (see [Permission Sets](/salesforce-app/salesforce-app-permission-sets)). Custom permissions differ from Permission Sets in that they: - Control specific **features** and **actions** (not object access) - Enable/disable **UI elements** like buttons and menu items - Follow a **hierarchical logic** where generic permissions override platform-specific ones --- ## Permission Hierarchy The Fours permission model uses a hierarchical structure where **generic permissions override platform-specific permissions**: ``` GENERIC (applies to all platforms) ├─ Create_Offer ────────► Can create offers for ANY platform ├─ Read_Offer ──────────► Can read offers from ANY platform ├─ Create_Referral ─────► Can create referrals for ANY platform └─ Read_Referral ───────► Can read referrals from ANY platform PLATFORM-SPECIFIC (limited to one platform) ├─ AWS │ ├─ Write_AWS_Offer │ ├─ Read_AWS_Offer │ ├─ Write_AWS_Referral │ └─ Read_AWS_Referral ├─ Azure │ ├─ Write_Azure_Offer │ ├─ Read_Azure_Offer │ ├─ Write_Azure_Referral │ └─ Read_Azure_Referral ├─ GCP │ ├─ Write_GCP_Offer │ ├─ Read_GCP_Offer │ ├─ Write_GCP_Referral │ └─ Read_GCP_Referral └─ Snowflake ├─ Write_SNOWFLAKE_Offer └─ Read_SNOWFLAKE_Offer ``` :::note If a user has a **generic permission** (e.g., `Create_Offer`), they automatically have access to all platforms without needing platform-specific permissions. ::: --- ## Offer Permissions ### Generic Offer Permissions | Permission | API Name | Description | UI Effect | | ---------- | -------- | ----------- | --------- | | Create Offer | `Create_Offer` | Create offers for any marketplace | Shows "New Offer" button, enables offer creation flows | | Read Offer | `Read_Offer` | View offers from any marketplace | Shows offer records and list views for all platforms | ### Platform-Specific Write Permissions These permissions allow creating and modifying offers for a specific cloud platform only. | Permission | API Name | Description | | ---------- | -------- | ----------- | | Write AWS Offer | `Write_AWS_Offer` | Create/modify AWS marketplace offers | | Write Azure Offer | `Write_Azure_Offer` | Create/modify Azure marketplace offers | | Write GCP Offer | `Write_GCP_Offer` | Create/modify GCP marketplace offers | | Write Snowflake Offer | `Write_SNOWFLAKE_Offer` | Create/modify Snowflake marketplace offers | ### Platform-Specific Read Permissions These permissions allow viewing offers for a specific cloud platform only. | Permission | API Name | Description | | ---------- | -------- | ----------- | | Read AWS Offer | `Read_AWS_Offer` | View AWS marketplace offers | | Read Azure Offer | `Read_Azure_Offer` | View Azure marketplace offers | | Read GCP Offer | `Read_GCP_Offer` | View GCP marketplace offers | | Read Snowflake Offer | `Read_SNOWFLAKE_Offer` | View Snowflake marketplace offers | --- ## Referral (Co-Sell) Permissions ### Generic Referral Permissions | Permission | API Name | Description | UI Effect | | ---------- | -------- | ----------- | --------- | | Create Referral | `Create_Referral` | Create referrals for any cloud partner | Shows referral creation buttons for all platforms | | Read Referral | `Read_Referral` | View referrals from any cloud partner | Shows referral records and list views for all platforms | ### Platform-Specific Write Permissions | Permission | API Name | Description | | ---------- | -------- | ----------- | | Write AWS Referral | `Write_AWS_Referral` | Create/modify AWS co-sell referrals | | Write Azure Referral | `Write_Azure_Referral` | Create/modify Azure co-sell referrals | | Write GCP Referral | `Write_GCP_Referral` | Create/modify GCP co-sell referrals | ### Platform-Specific Read Permissions | Permission | API Name | Description | | ---------- | -------- | ----------- | | Read AWS Referral | `Read_AWS_Referral` | View AWS co-sell referrals | | Read Azure Referral | `Read_Azure_Referral` | View Azure co-sell referrals | | Read GCP Referral | `Read_GCP_Referral` | View GCP co-sell referrals | --- ## Funding Permissions These permissions control access to **AWS Funding** features (MDF/POC funding applications and the funding approval workflow). Because they are evaluated as Salesforce custom permissions, they apply whether the permission set is assigned directly or through a permission set group. | Permission | API Name | Description | UI Effect | | ---------- | -------- | ----------- | --------- | | Read Funding | `Read_Funding` | View funding applications | Shows funding records and list views on the **Funding V2 (Suger)** tab | | Write Funding | `Write_Funding` | Create and modify funding applications | Enables funding creation and edit actions | `Read_Funding` is granted by the **Suger Funding** and **Suger Funding (Read Only)** permission sets; `Write_Funding` is granted by **Suger Funding**. :::note Funding approval reuses the shared **Approve Cosell** (`Approve_Cosell`) permission. ::: --- ## Approval Permissions These permissions control access to approval workflows for offers and co-sell referrals. | Permission | API Name | Description | UI Effect | | ---------- | -------- | ----------- | --------- | | Approve Offer | `Approve_Offer` | Approve/reject offers in approval workflow | Shows approval section and actions on offer records | | Approve Cosell | `Approve_Cosell` | Approve/reject co-sell referrals | Shows approval actions on referral records | :::note The **Approve Offer** permission only functions when the **Enable Approval Process** toggle is active in Fours Settings. ::: --- ## Contact Management Permissions These permissions control the ability to manage contacts on offer records. | Permission | API Name | Description | UI Effect | | ---------- | -------- | ----------- | --------- | | Modify Offer Contacts | `Modify_Offer_Contacts` | Add/remove contacts from offers, and file contacts under a product line | Shows "Add Contact" button on offer records, and **Add contact** / remove on the Buyer Contacts panel of Suger Account Insights | | Notify Offer Contacts | `Notify_Offer_Contacts` | Send notifications to offer contacts | Shows "Notify Contacts" button on offer records | :::tip Users with the **Create Offer** permission automatically have access to contact management features on offer records, even without these specific permissions. The [Buyer Contacts](/salesforce-app/salesforce-app-page-components/#buyer-contacts) panel of Suger Account Insights is the exception: its **Add contact** and remove controls check **Modify Offer Contacts** alone. ::: --- ## Administrative Permissions | Permission | API Name | Description | UI Effect | | ---------- | -------- | ----------- | --------- | | Modify Settings | `Modify_Settings` | Access and modify Fours settings | Shows Settings tab and allows configuration changes | :::note **System Administrators** automatically have `Modify_Settings` capabilities regardless of whether this permission is explicitly assigned. ::: --- ## Permission Checking Logic The Fours app uses the following logic to determine user access: ### For Offer Creation 1. Check if user has `Create_Offer` → Grant access to **all** platforms 2. If not, check platform-specific permission (e.g., `Write_AWS_Offer`) 3. If neither, access is denied ### For Offer Reading 1. Check if user has `Create_Offer` → Writers can read (grant access) 2. If not, check if user has `Read_Offer` → Grant access to **all** platforms 3. If not, check platform-specific permission (e.g., `Read_AWS_Offer`) 4. If none, access is denied ### For Product Filtering When creating offers, the product list is filtered based on the user's write permissions: - If user has `Create_Offer` → Show products for **all** platforms - If user has only `Write_AWS_Offer` → Show only AWS products - Multiple platform permissions combine (e.g., `Write_AWS_Offer` + `Write_GCP_Offer` shows both) --- ## UI Elements Controlled by Permissions ### Tab Visibility | Tab | Required Permission(s) | | --- | ---------------------- | | Products | Any marketplace offer permission | | Offers | Any marketplace offer permission | | Entitlements | Any marketplace offer permission | | Buyers | Any marketplace offer permission | | Referrals | Any co-sell referral permission | | Funding | `Read_Funding` or `Write_Funding` | | Settings | `Modify_Settings` or System Administrator | ### Action Buttons | Button/Action | Required Permission(s) | | ------------- | ---------------------- | | Create Offer | `Create_Offer` OR any `Write_*_Offer` | | Edit Offer | Platform-specific write permission for the offer's partner | | Approve/Reject Offer | `Approve_Offer` | | Add Contact | `Modify_Offer_Contacts` OR `Create_Offer` | | Add contact / remove (Buyer Contacts panel) | `Modify_Offer_Contacts` only | | Notify Contacts | `Notify_Offer_Contacts` OR `Create_Offer` | | Create Referral | `Create_Referral` OR any `Write_*_Referral` | | Edit Referral | Platform-specific write permission for the referral's partner | | Approve/Reject Referral | `Approve_Cosell` | | Delete Referral | Uses native Salesforce object permissions (`isDeletable()`) | --- ## Permission Set Assignments The following table shows which custom permissions are included in each permission set: ### Suger User (Full Access) The **Suger User** permission set grants access to ALL custom permissions across all platforms: | Permission Category | Permissions Included | | ------------------- | -------------------- | | Generic Offer | `Create_Offer`, `Read_Offer` | | AWS Offer | `Write_AWS_Offer`, `Read_AWS_Offer` | | Azure Offer | `Write_Azure_Offer`, `Read_Azure_Offer` | | GCP Offer | `Write_GCP_Offer`, `Read_GCP_Offer` | | Snowflake Offer | `Write_SNOWFLAKE_Offer`, `Read_SNOWFLAKE_Offer` | | Generic Referral | `Create_Referral`, `Read_Referral` | | AWS Referral | `Write_AWS_Referral`, `Read_AWS_Referral` | | Azure Referral | `Write_Azure_Referral`, `Read_Azure_Referral` | | GCP Referral | `Write_GCP_Referral`, `Read_GCP_Referral` | | Contact Management | `Modify_Offer_Contacts`, `Notify_Offer_Contacts` | :::note **Suger User** is the standard permission set for human users requiring full access to the Fours app across all cloud platforms. Use platform-specific permission sets for restricted access. ::: ### Marketplace Permission Sets | Permission | Marketplace Read Only | Marketplace AWS | Marketplace Azure | Marketplace GCP | Marketplace Snowflake | | ---------- | :------------------: | :-------------: | :---------------: | :-------------: | :-------------------: | | Read_Offer | ✓ | | | | | | Write_AWS_Offer | | ✓ | | | | | Read_AWS_Offer | | ✓ | | | | | Write_Azure_Offer | | | ✓ | | | | Read_Azure_Offer | | | ✓ | | | | Write_GCP_Offer | | | | ✓ | | | Read_GCP_Offer | | | | ✓ | | | Write_SNOWFLAKE_Offer | | | | | ✓ | | Read_SNOWFLAKE_Offer | | | | | ✓ | | Modify_Offer_Contacts | | ✓ | ✓ | ✓ | | | Notify_Offer_Contacts | | ✓ | ✓ | ✓ | | ### Co-Sell Permission Sets | Permission | Cosell | Cosell AWS | Cosell Azure | Cosell GCP | Cosell Read Only | | ---------- | :---------------: | :--------: | :----------: | :--------: | :--------------: | | Create_Referral | ✓ | | | | | | Read_Referral | ✓ | | | | ✓ | | Write_AWS_Referral | ✓ | ✓ | | | | | Read_AWS_Referral | ✓ | ✓ | | | ✓ | | Write_Azure_Referral | ✓ | | ✓ | | | | Read_Azure_Referral | ✓ | | ✓ | | ✓ | | Write_GCP_Referral | ✓ | | | ✓ | | | Read_GCP_Referral | ✓ | | | ✓ | ✓ | ### Administrative Permission Sets | Permission | Suger Integrator | Suger Approval Offer | Suger Approval Cosell | | ---------- | :--------------: | :------------: | :-------------------: | | All Offer Permissions | ✓ | | | | All Referral Permissions | ✓ | | | | Approve_Offer | ✓ | ✓ | | | Approve_Cosell | ✓ | | ✓ | | Modify_Settings | ✓ | | | | Modify_Offer_Contacts | ✓ | | | | Notify_Offer_Contacts | ✓ | | | :::note **Suger Approval Offer** grants Approve_Offer only (marketplace offers). **Suger Approval Cosell** grants Approve_Cosell only (co-sell referrals). Assign both if a user needs to approve both kinds. ::: :::note **Suger Integrator** is dedicated for integration/API users (not human users). It has the same custom permissions as **Suger User**, plus `Approve_Offer`, `Approve_Cosell`, and `Modify_Settings` for full system access. ::: --- ## Best Practices ### Principle of Least Privilege Assign the most restrictive permission set that meets the user's needs: - For human users who need full access to the Fours app, use `Suger_User` - For users who only work with one cloud platform, use platform-specific permission sets - Reserve `Suger_Integrator` for integration/API users only (not human users) ### Permission Set Groups Consider creating Permission Set Groups to combine multiple permissions: - **AWS Power User**: `Suger_User_Marketplace_AWS` + `Suger_User_Cosell_AWS` - **Multi-Cloud Viewer**: `Suger_User_Marketplace_Read` + `Suger_User_Cosell_Read` ### Testing Permissions Before deploying permission changes to production: 1. Create a test user with the target permission set 2. Verify tab visibility matches expectations 3. Confirm action buttons appear/hide correctly 4. Test actual CRUD operations to verify object-level access --- Source: https://doc.fours.com/salesforce-app/salesforce-app-reports/ # Reports The Fours Salesforce App ships with a set of **Custom Report Types** and pre-built **Reports** that give your team out-of-the-box visibility into marketplace offers, entitlements, revenue, co-sell referrals, funding activity, and the partner contacts mapped to your accounts. This page documents each report type — what object it's built on, what data it joins together, and what fields it exposes. --- ## Overview If you manage marketplace sales across multiple cloud providers, reporting usually means switching between AWS, Azure, and GCP, exporting CSV files, and manually combining them into a single spreadsheet. This creates three common problems: - Data is fragmented across different systems. - Reports take hours to build and validate. - It's hard to compare performance across clouds consistently. Fours acts as the data layer between the cloud marketplaces and your CRM. It standardizes marketplace data from AWS, Azure, and GCP into a single structure before syncing it into Salesforce. Once connected, all marketplace activity shows up in one consistent format — regardless of which cloud it originated from — so you can report on it directly in Salesforce. ### How Fours Normalizes Marketplace Data A common question from RevOps teams is whether they need separate reporting logic for each cloud. With Fours, the answer is no. Fours maps AWS, Azure, and GCP marketplace objects into a unified data model so they behave consistently inside Salesforce. This means: - A deal from AWS looks the same as a deal from GCP. - Fields and object types are consistent across all clouds. - One reporting model works across all marketplace activity. This removes the need to build and maintain cloud-specific reporting logic. ### Before vs. After Fours | Reporting task | Without Fours | With Fours | | --- | --- | --- | | Track pipeline across clouds | Export separate reports from AWS, Azure, and GCP, then combine manually | View all marketplace opportunities in a single Salesforce dashboard | | Monitor deal status | Check each cloud portal individually for updates | See real-time status updates directly in Salesforce | | Build leadership reports | Download and merge multiple CSV files every reporting cycle | Run unified reports directly from Salesforce with standardized data | --- ## What Your Team Can Track Once Fours is connected to Salesforce, marketplace data can be used directly in dashboards and reports. ### Sales and Growth Use these to understand how your marketplace business is growing over time: - Number of accepted offers per month - Average time from offer creation to buyer acceptance - Top customers ranked by marketplace revenue Instead of waiting for a finance report at the end of the month, your sales team can see in real time which deals have closed and which are still pending buyer action. ### Funnel Performance Use these to track how opportunities move through your co-sell pipeline: - Volume of opportunities shared to cloud marketplaces (outbound referrals) - Marketplace close rates by cloud provider - Conversion metrics across AWS, Azure, and GCP side by side If your team is co-selling with a cloud partner, these metrics tell you which partnerships are actually driving closed revenue and which ones need attention. ### Financial Health Use these to stay on top of payment and contract status without chasing down individual deals: - Overdue payments and past-due contract flags - Refund trends over time - Transaction volume broken down by country or region Your Finance team gets a live view of payment health instead of waiting for end-of-month reconciliation. --- ## Where to Find Reports 1. In Salesforce, click **Reports** in the App Launcher. 2. Open the **All Folders** view and look for: - **Suger Reports** — pre-built dashboards and reports for co-sell and marketplace activity. - **Suger Marketplace Operations Reports** — operations-focused reports (offers, entitlements, revenue). 3. To build your own report, click **New Report** and search for any report type with the **"Suger"** prefix. To view pre-built dashboards: 1. Go to the **Dashboards** section in Salesforce. 2. Search for Suger dashboards (for example, marketplace or co-sell dashboards). 3. Apply filters such as date range or cloud provider. 4. Drill into individual reports to explore deal-level details. :::info If dashboards or reports are not visible, your team may need to complete the initial CRM integration setup. See [Integrate Salesforce with Fours](/integrations/salesforce/). ::: --- ## Custom Report Types All Fours report types are listed below grouped by primary domain. Field coverage notes refer to which Fours custom-object fields are queryable; standard Salesforce system fields (`Id`, `Owner`, `Name`, `CreatedDate`, `LastModifiedDate`, etc.) are included on every report type and are not listed individually. ### Marketplace Report Types | Report Type | Label | Base Object | Joined Objects | Purpose | | ----------- | ----- | ----------- | -------------- | ------- | | `Suger_Offers` | Suger (Offers) | `Offer__c` | — | Single-object report on marketplace offers. Includes status, type, buyer info, dates, approval status, AWS Net Payment Term, and external IDs from each cloud marketplace. | | `Suger_Offers_with_Dimensions` | Suger Offers and Offer Dimensions | `Offer__c` | `OfferDimension__c` (child) | Offers, including AWS Net Payment Term, joined to their metering dimensions. Use when you need per-dimension pricing (Rate, Key, Plan) alongside offer attributes. | | `Entitlements_Suger` | Cloud Entitlements (Suger) | `Entitlement__c` | — | Single-object report on customer entitlements. Includes financial roll-ups (Invoiced, Collectable, Disbursed amounts), product, offer, and buyer linkage, and the entitlement's **AWS Net Payment Term**. | | `Suger_Entitlements_and_Revenue_Records` | Suger Entitlements and Revenue Records | `Entitlement__c` | `RevenueRecord__c` (child) | Entitlements joined to their per-transaction revenue records. Use for revenue breakdown by entitlement, invoice date, or disbursement period. Also exposes the linked **Account** — the lookup itself plus **Account Name** and **Account ID** via lookup — so revenue can be grouped and filtered by customer account. The entitlement's **AWS Net Payment Term** is available too. | | `Suger_Revenue_Records` | Suger Revenue Records | `RevenueRecord__c` | — | Revenue transactions tracking payments from buyers and disbursements from cloud partners. Includes invoice amount, collectable amount, disburse amount, and partner fees. | | `Suger_Offer_Payment_Installments` | Suger Offer Payment Installments | `OfferPaymentInstallment__c` | — | The payment schedule behind an offer, with the parent offer reachable through the Offer lookup. Exposes Charge Date, Amount, Original Amount, Discount Percentage, Credit, and Currency — use it to report on prepay schedules and negotiated free credit rather than on offer totals. | | `Suger_Fundings` | Suger (Fundings) | `Funding__c` | — | AWS Funding requests, including status, opportunity linkage, approval workflow, and claim amounts, plus the cash request's PO number and payee profile, the ACE opportunity ID, the AWS account, issued amount, expiration date, fulfillment types, and partner contact emails. | ### Co-Sell Report Types | Report Type | Label | Base Object | Joined Objects | Purpose | | ----------- | ----- | ----------- | -------------- | ------- | | `Cloud_Referrals` | Cloud Referrals (Suger) | `Referral__c` | — | Single-object report on all co-sell referrals. Includes common fields plus all AWS, Azure, and GCP cloud-specific fields (`AWS_*`, `AZURE_*`, `GCP_*`). | | `Opportunities_with_Cloud_Referrals` | Opportunities with Cloud Referrals | `Opportunity` | `Referral__c` (via `Referrals__r`) | Salesforce Opportunities joined to their Fours referrals. Useful for measuring opportunities that have an associated co-sell referral. | | `Cosell_Opportunities_with_Cloud_Referrals` | Co-Sell Opportunities with Cloud Referrals | `Opportunity` | `Referral__c` (via `Referrals__r`) | Variant of the above scoped to co-sell-tagged opportunities. | | `opportunities_trending` | Co-Sell Opportunities Trending | `Opportunity` | `Referral__c` (via `Referrals__r`) | **DEPRECATED.** Earlier version of the Opportunities-with-Referrals report type. Kept for backwards compatibility with existing dashboards. Use `Opportunities_with_Cloud_Referrals` for new reports. | **Invitation Message** (`AWS_InvitationMessage__c`) is selectable as a column on the referral report types — the covering note the sender attached to an AWS engagement invitation. It is an invitation-only field, so it stays populated after acceptance and is one way to identify, after the fact, that a referral arrived as an inbound invitation. ### Partner Contact Report Types These report on the partner contacts — such as the AWS, Azure, and GCP sellers on your deals — mapped to your Accounts, so partner-seller activity can be lined up against your own accounts and campaigns. | Report Type | Label | Base Object | Joined Objects | Purpose | | ----------- | ----- | ----------- | -------------- | ------- | | `Accounts_with_Suger_Partner_Contacts` | Accounts with Suger Partner Contacts | `Account` | `Contact_Account__c` (via `Contact_Accounts__r`, with or without) | Accounts and the partner sellers mapped to them, including accounts with no open opportunities. Carries the **Collaboration Score**. | :::note **Three partner-contact report types are no longer installed with the package.** **Opportunities with Suger Partner Contacts**, **Suger Partner Contact Accounts**, and **Suger Partner Contact Opportunities** — with the **[Suger] Partner Contacts by Opportunity** report built on the first — were taken out because every packaged custom report type counts against your org's custom report type limit, and orgs already at that limit could not upgrade. An org that installed them earlier keeps them; new installs do not get them. ::: Group or filter on **Link Source** to keep confirmed referral activity (`Referral`) apart from domain matches Fours inferred (`Predicted`) and mappings an admin uploaded (`Upload`). The contact's name, email, role, and partner are copied onto each row, because an Account- or Opportunity-based report cannot reach the partner contact record itself — see [Contact_Account__c](/salesforce-app/salesforce-app-custom-objects/#contact_account__c) for every field and for when rows are written. Every Fours user, co-sell, marketplace, and funding permission set can read these objects, so anyone with one of those sets can run the reports. ### Cross-Domain Report Types | Report Type | Label | Base Object | Joined Objects | Purpose | | ----------- | ----- | ----------- | -------------- | ------- | | `Opportunities_Suger` | Opportunities - Offers (Suger) | `Opportunity` | `Offer__c` (via `Offers__r`) | Opportunities joined to their Fours offers, including AWS Net Payment Term. Useful when an Opportunity drives one or more marketplace offers and you want both on a single row. | | `Opportunities_with_Suger_Entitlements` | Opportunities with Suger Entitlements | `Opportunity` | `Offer__c` → `Entitlement__c` (two-level join via `Offers__r.Entitlements__r`) | Opportunities all the way through to fulfilled entitlements, with AWS Net Payment Term available from the offer. Tracks the full sales-to-fulfillment lifecycle on one report. | --- ## Pre-Built Reports The Fours app installs two folders of pre-built reports: ### Suger Reports Focused on co-sell activity and pipeline health: - **All Co-Sell Opportunities** — every opportunity tagged with a referral - **All Co-Sell Opportunities by Week** — co-sell volume trend - **Inbound / Outbound Co-Sell Opportunities by Week** — directional volume trends - **Win Ratio (Current FY)** — co-sell-influenced win rate - **CoSell Opportunity Leaderboard** — leaderboard by opportunity owner - **CoSell Opportunities by AWS AM / AWS ISM / Sales Stage / Referral Type / PTB** — segmentation breakdowns - **Days to Close** (Opportunity Created Date / Referral Created Date) — cycle-time metrics - **Inbound CoSell Opportunities by AWS AM / MS Contact** — partner-rep attribution - **MS All Referrals by MACC Eligibility** — Microsoft MACC eligibility breakdown - **Opportunities without CoSell** — uncovered pipeline - **[Suger] Partner Contacts by Account** — the partner sellers mapped to each account, grouped by **Link Source**, including accounts with no open opportunities - **[Suger] Partner Contacts by Opportunity** — the partner sellers associated with each opportunity, grouped by **Link Source**, with the opportunity amount summed. No longer installed with the package; see [Partner Contact Report Types](#partner-contact-report-types) This folder also carries a few marketplace reports alongside the co-sell ones: - **All Marketplace Offers** — offer-level inventory of all marketplace activity, with **AWS Net Payment Term** included as a column - **All Active Entitlements Report** — the contracts currently running - **Opportunities with Suger Entitlements** — opportunities followed through to fulfilled entitlements - **Suger Revenue Records** / **Suger Entitlements and Reveue Records** — transaction-level revenue ### Suger Marketplace Operations Reports Focused on marketplace transactions and revenue ops. The folder installs sixteen reports: | Report | What it answers | | --- | --- | | **Current FY Accepted Private Offers** | Private offers accepted so far this fiscal year. | | **Current FQ Accepted Private Offe** | The same, scoped to the current fiscal quarter. | | **FQ Accepted Private Offers SUM** | Fiscal-quarter accepted private offers, summed. | | **All Time Accepted Private Offers** | Every private offer ever accepted. | | **Private Offers Expiring This Week** | Offers whose acceptance window closes within the week. | | **Contracts Expiring this Month** | Entitlements reaching their end date this month. | | **Active Public Offers Over Time** | Public (listing) offer volume as a trend. | | **Accepted Offer Distribution by Country** | Where accepted offers are coming from geographically. | | **Current FY Pipeline by Cloud** | This fiscal year's marketplace pipeline split by cloud. | | **Current FY Sum/Average Deal Size** | Deal-size totals and averages for the current fiscal year. | | **Previous FY Sum/Average Deal Size** | The same for the prior fiscal year, for comparison. | | **Marketplace Average Deal Size (12 month)** | Rolling twelve-month average deal size. | | **Average for Offer Acceptance** | How long buyers take to accept. | | **Marketplace Revenue by Product and Cloud** | Revenue broken out by product and cloud. | | **Marketplace Leaderboard** | Ranking by marketplace activity. | | **Past-Due Marketplace Disbursements** | Disbursements the cloud partner has not paid on time. | **AWS Net Payment Term** is a selectable column in two places. The offer's field is on the four Offer/Opportunity report types that reach an offer — `Suger_Offers`, `Suger_Offers_with_Dimensions`, `Opportunities_Suger`, and `Opportunities_with_Suger_Entitlements`. The entitlement's own copy is on `Entitlements_Suger` and `Suger_Entitlements_and_Revenue_Records`. Both are off by default; add them from the field list. The revenue-record **Payment Terms** field is separate: on an AWS record it follows the accepted AWS net payment term, and otherwise counts the days from invoice date to payment due date — see [Custom Objects](/salesforce-app/salesforce-app-custom-objects/). You can clone any pre-built report and adapt it; the underlying Custom Report Types listed above are the foundation. --- ## Building Your Own Report To build a custom report using Fours data: 1. In Salesforce, go to **Reports → New Report**. 2. In the report type picker, search for **"Suger"** to filter to Fours report types. 3. Select the report type matching the data you need (see the tables above). 4. Add columns from the available fields. All custom fields on the base object (and joined child objects, where applicable) are queryable. 5. Apply filters and groupings as you would with any Salesforce report. :::tip For complex multi-object analysis (e.g., Opportunity → Offer → Entitlement → Revenue), start with the highest-level joined report type (`Opportunities_with_Suger_Entitlements`) — it gives you the longest reach into the data model in a single report. ::: --- ## Field Reference For per-field definitions, see the [Custom Objects](/salesforce-app/salesforce-app-custom-objects/) page — every field exposed in a report type is documented on its parent object's table. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-apex-actions/ # Apex Actions This guide documents the Apex Actions (Invocable Methods) provided by the Fours Salesforce App. These actions can be used in Salesforce Flows, Process Builder, and other automation tools to integrate co-sell workflows. ## Overview Fours provides six Apex Actions for co-sell automation: | Action | Description | Supported Partners | | ------ | ----------- | ------------------ | | Check If Opportunity Shared | Check if an opportunity has been shared as a referral | AWS, Azure, GCP | | Co-Sell | Share an opportunity with a cloud partner (waits for completion, backfills to Salesforce) | AWS, Azure, GCP | | Co-Sell (Fire and Forget) | Share an opportunity without waiting for completion | AWS, Azure, GCP | | Process Inbound Co-Sell Referral | Accept or decline an inbound referral (Azure referral or AWS engagement invitation) | Azure, AWS | | Update Referral Linkage | Link a referral to an opportunity and/or an account | AWS, Azure, GCP, Fours | | Update AWS Referral | Update business fields on an AWS co-sell referral | AWS only | ### How an action reaches the cloud partner Every action runs the same three-system path: your Flow calls an Apex method in the managed package, the package calls Fours over HTTP, and Fours talks to the cloud partner. Where the actions differ is what happens *after* Fours accepts the request — whether the Flow waits for the partner, and whether a Salesforce record comes back in the same run. ```d2 direction: down group: "Your Salesforce org" { flow: "Flow / Process Builder\nAction element" apex: "Fours Apex invocable method" perm: "Permission check\nWrite_AWS_Referral /\nWrite_Azure_Referral /\nWrite_GCP_Referral" { shape: diamond } record: "Referral__c record\nlinked to the Opportunity" flow -> apex: "inputs" apex -> perm } denied: "Success = false\nMessage explains why" suger: "Fours\ncreate / update workflow" partner: "Cloud partner\nAWS Partner Central (ACE)\nMicrosoft Partner Center\nGoogle Cloud Partner Network" wait: "Does this action wait?" { shape: diamond } ff: "No Salesforce record.\nLook the referral up in Fours\nby the returned Referral ID" group.perm -> denied: "no permission,\nor a value failed validation" group.perm -> suger: "HTTPS callout" suger -> partner: "submits the referral" suger -> wait wait -> group.record: "Co-Sell — polls ~12s,\nthen backfills" wait -> ff: "Co-Sell (Fire and Forget) —\nreturns immediately" partner -> group.record: "later inbound sync\nfills in status and scores" ``` :::note Because every action performs an HTTP callout, place it on the **Run Asynchronously** path of a record-triggered Flow. `Success = true` means Fours accepted the request — for the fire-and-forget and AWS-accept paths it does **not** mean the partner has finished processing it. ::: --- ## Check If Opportunity Shared **API Name:** `CosellCheckSharedOppApexAction` **Label:** Check If Opportunity Shared **Description:** Check if an opportunity has already been shared as a co-sell referral with a specific partner or any partner. ### Supported Partners AWS, Azure, GCP, or ANY (checks all partners) ### Inputs | Parameter | Type | Required | Description | | --------- | ---- | :------: | ----------- | | Opportunity ID | Id | Yes | Salesforce Opportunity ID to check | | Partner | String | No | Partner to check: `AWS`, `AZURE`, `GCP`, or `ANY`. Defaults to `ANY` if not specified | ### Outputs | Parameter | Type | Description | | --------- | ---- | ----------- | | Success | Boolean | Whether the operation completed successfully | | Has Been Shared | Boolean | Whether the opportunity has been shared with the specified partner | | Message | String | Descriptive message about the result | ### Example Use Cases - Prevent duplicate referral submissions by checking if an opportunity was already shared - Conditionally show/hide co-sell buttons based on sharing status - Validate before triggering co-sell automation --- ## Co-Sell (Share Opportunity) **API Name:** `CosellShareReferralAsyncApexAction` **Label:** Co-Sell **Description:** Share an opportunity with a co-sell partner. This action creates a new referral in the cloud partner's system and backfills the referral record to Salesforce. ### Supported Partners AWS, Azure, GCP ### Inputs | Parameter | Type | Required | Description | | --------- | ---- | :------: | ----------- | | Partner | String | Yes | Cloud partner: `AWS`, `AZURE`, or `GCP` | | Opportunity ID | Id | No | Salesforce Opportunity ID to share. Required unless **Referral Payload (JSON)** is provided | | Referral Payload (JSON) | String | No | A complete referral payload as a JSON string (the same envelope used by the [Create a Referral API](/cosell/cosell-referral-api/)). When provided, the field-mapping preview is skipped and this payload is submitted as-is | ### Outputs | Parameter | Type | Description | | --------- | ---- | ----------- | | Success | Boolean | Whether the referral was created successfully | | Message | String | Error message if the operation failed | | Referral ID | Id | Salesforce Referral record ID (if successful) | | External Referral ID | String | Fours Referral ID (returned even on partial failure) | ### Behavior 1. Validates user has write permission for the specified partner 2. Builds the referral payload — from the supplied **Referral Payload (JSON)** if provided, otherwise from the opportunity via field mapping 3. Creates the referral in the cloud partner's system via Fours 4. Polls for workflow completion (up to ~12 seconds) 5. Backfills the referral record to Salesforce :::note Provide **either** an Opportunity ID or a Referral Payload (JSON). If both are set, the payload is submitted and the Opportunity ID is used only to link the referral to that CRM record. This action performs HTTP callouts and may take several seconds to complete, so on a record-triggered Flow place it on the **Run Asynchronously** path. The external referral ID is returned even if later steps fail, allowing for manual recovery. ::: --- ## Co-Sell (Fire and Forget) **API Name:** `CosellShareReferralAction` **Label:** Co-Sell (Fire and Forget) **Description:** Share an opportunity with a co-sell partner **without waiting** for the create to finish. The action returns as soon as the create workflow starts — it does not poll for completion or backfill a Salesforce `Referral__c` record. Use it when you don't need the result in the same Flow run. ### Supported Partners AWS, Azure, GCP ### Inputs | Parameter | Type | Required | Description | | --------- | ---- | :------: | ----------- | | Partner | String | Yes | Cloud partner: `AWS`, `AZURE`, or `GCP` | | Opportunity ID | Id | No | Salesforce Opportunity ID to share. Required unless **Referral Payload (JSON)** is provided | | Referral Payload (JSON) | String | No | A complete referral payload as a JSON string (the same envelope used by the [Create a Referral API](/cosell/cosell-referral-api/)). When provided, the field-mapping preview is skipped and this payload is submitted as-is | ### Outputs | Parameter | Type | Description | | --------- | ---- | ----------- | | Success | Boolean | Whether the create workflow started successfully | | Message | String | Error message if the operation failed | | Referral ID | String | Fours Referral ID — the external referral ID (no Salesforce record is created) | | Partner | String | The partner the referral was shared with | ### Behavior 1. Validates user has write permission for the specified partner 2. Builds the referral payload — from the supplied **Referral Payload (JSON)** if provided, otherwise from the opportunity via field mapping 3. Creates the referral in the cloud partner's system via Fours and returns immediately :::note Provide **either** an Opportunity ID or a Referral Payload (JSON) (same precedence as **Co-Sell**). Unlike **Co-Sell**, this action does not wait for the partner or backfill a Salesforce record — `Success = true` means the create workflow was submitted, not that the partner accepted it. Look the referral up in Fours by the returned Referral ID to confirm the final status. On a record-triggered Flow, place it on the **Run Asynchronously** path (it performs an HTTP callout). ::: --- ## Process Inbound Co-Sell Referral **API Name:** `CosellProcessInboundReferralApexAction` **Label:** Process Inbound Co-Sell Referral **Description:** Accept or decline an inbound co-sell referral from a cloud partner. ### Supported Partners **Azure and AWS.** For AWS the action processes a pending **engagement invitation** — the inbound form an AWS-originated referral arrives in. GCP inbound referrals must still be processed through the partner portal or the Fours UI. ### Inputs | Parameter | Type | Required | Description | | --------- | ---- | :------: | ----------- | | Partner | String | Yes | `AZURE` or `AWS` | | Referral ID | String | Yes | Fours Referral ID (not the Salesforce record ID) | | Decision | String | Yes | `ACCEPT` or `DECLINE` | | Reason | String | No | Reason for declining (only applicable when declining). For AWS this is passed to Partner Central, which requires a single line of at most 80 characters | ### Outputs | Parameter | Type | Description | | --------- | ---- | ----------- | | Success | Boolean | Whether the operation completed successfully | | Message | String | Error message if the operation failed | ### Behavior **Azure — when accepting:** - Updates the referral status to `Active` with substatus `Accepted` - Invokes the pre-acceptance webhook (if configured) **Azure — when declining:** - Updates the referral status to `Closed` with substatus `Declined` - Sets the status reason with the provided decline reason **AWS — when accepting:** - Accepts the engagement invitation in AWS Partner Central (ACE) - Returns as soon as AWS takes the request. AWS creates the opportunity asynchronously, so the referral's status and opportunity fields are filled in shortly afterwards by the inbound sync, not by this action **AWS — when declining:** - Rejects the engagement invitation in AWS Partner Central and sets the referral to `REJECTED` - The decline reason is recorded on the Fours referral and sent on to AWS Partner Central. When no reason is given, AWS is sent `Other` - If auto-delete is enabled for the org, the linked CRM records are removed **AWS — when AWS refuses the accept or decline:** - The action returns `Success = false` with the error in `Message` - The failure is also recorded on the referral: the invitation's status badge reads **Update Failed:** followed by the reason until a later accept or decline succeeds. The referral's own status is not changed :::warning For AWS the invitation must still be **pending**. If it has already been accepted, rejected or expired — or if the referral has already progressed to a full AWS opportunity — the action returns `Success = false` with the reason, and nothing is changed. ::: :::note GCP is not supported: passing `GCP` returns `Success = false` with `only AWS and Azure are supported`. ::: --- ## Update Referral Linkage **API Name:** `CosellUpdateReferralLinkageApexAction` **Label:** Update Referral Linkage **Description:** Link a referral to a Salesforce opportunity, an account, or both. Use it to associate a referral with CRM records by hand, or to correct the linkage after the referral was created. ### Supported Partners AWS, Azure, GCP, Fours (partner-to-partner co-sell) ### Inputs | Parameter | Type | Required | Description | | --------- | ---- | :------: | ----------- | | Partner | String | Yes | Partner: `AWS`, `AZURE`, `GCP`, or `SUGER`. Case-insensitive | | Referral ID | String | Yes | Fours Referral ID to update | | Opportunity ID | Id | No | Salesforce Opportunity ID to link. **At least one of Opportunity ID or Account ID is required** | | Account ID | Id | No | Salesforce Account ID to link. **At least one of Opportunity ID or Account ID is required** | ### Outputs | Parameter | Type | Description | | --------- | ---- | ----------- | | Success | Boolean | Whether the linkage was updated successfully | | Message | String | `No changes; skipped.` when the referral already holds the IDs you supplied; the reason on failure; otherwise empty | :::note **A blank ID is left alone, not cleared.** Leaving Opportunity ID or Account ID empty means *keep whatever Fours already holds* — it does not unlink. That is what makes an account-only link safe: it cannot wipe an opportunity the referral is already attached to. To remove a link, use **Unlink** on the referral's Account card in Salesforce (and confirm **Clear Account**); this action cannot unlink. ::: ### Behavior 1. Rejects an unsupported partner, and rejects a request that supplies **neither** Opportunity ID nor Account ID — `opportunityId or accountId is required` — before spending a callout 2. Validates the user has write permission for the specified partner 3. Fetches the referral from Fours 4. Returns `Success = true` with `No changes; skipped.` when the referral already holds the IDs you supplied. An ID you did not supply never counts as a difference, so re-running an account-only link is a no-op rather than a write 5. Writes `salesforceOpportunityId` and `salesforceAccountId` — only the ones you supplied 6. For Azure **with** an Opportunity ID, also updates `externalReferenceId` in the Microsoft referral set, so the link reaches Microsoft Partner Center :::note Linking an account on its own takes the CRM-linkage-only path for every partner, Azure included: there is nothing for Microsoft to mirror, so the referral is not put in front of the partner update validator. An Azure link that carries an Opportunity ID behaves as before. ::: ## Update AWS Referral Fields **API Name:** `CosellUpdateAwsReferralApexAction` **Label:** Update AWS Referral **Description:** Update business fields on an existing AWS co-sell referral. Only the fields you supply are changed — leave a field out and it keeps its current value. A referral belonging to another partner is refused. ### Supported Partners AWS ### Inputs | Parameter | Type | Required | Description | | --------- | ---- | :------: | ----------- | | Referral ID | String | Yes | Fours Referral ID to update | | APN Programs | String | No | Semicolon-separated APN program names, e.g. `Migration Acceleration Program;Well-Architected`. Values must come from the AWS APN Program picklist. `Model Provider PARC` is accepted only on a referral AWS originated. Pass an **empty value** to remove every program | | Next Step | String | No | Next step on the opportunity, up to 255 characters | | Target Close Date | Date | No | Must be a future date (after today, UTC). AWS freezes this once the opportunity is Launched | | Customer Business Problem | String | No | The customer's situation and the problem they need solved, 20 to 2,000 characters | | Additional Comments | String | No | Free-text notes on the opportunity, up to 255 characters | ### Outputs | Parameter | Type | Description | | --------- | ---- | ----------- | | Success | Boolean | Whether the referral was updated | | Message | String | The fields updated on success, or the reason it was refused | | APN Programs | String | The full program list on the referral after the update, semicolon-separated | | Referral Status | String | The referral status as it stood **before** this update, e.g. `ACTIVE` or `ACTION_REQUIRED`. Fours recomputes the status while saving, and the push to AWS can change it again after that — re-read the referral if a Flow must branch on the new value | ### Behavior 1. Validates that at least one field was supplied — every field is optional, but a request that sets none is refused rather than costing two callouts to write the referral back unchanged — and that the user has write permission for the partner 2. Validates every supplied value **before any callout** and **refuses the whole update** if one fails: APN Programs must all be on the AWS APN Program picklist (an unrecognized value is rejected by AWS and blocks every later change to that referral), Target Close Date must be in the future, and the text fields must be within the lengths above. Fours would otherwise keep the old value or truncate silently, so it is caught here instead 3. Fetches the referral from Fours 4. Refuses a referral that belongs to another partner — the caller passes only a referral ID, so the referral's own partner decides 5. Refuses the update unless AWS has the opportunity at `Approved` or `Action Required`; AWS accepts changes in no other review status 6. Refuses the update when the opportunity is `Launched` or `Closed Lost`, because AWS does not accept changes after close 7. Refuses `Model Provider PARC` unless AWS originated the referral — AWS rejects it on a partner-originated opportunity, and that rejection blocks every later change to the referral. It stays editable on an inbound referral 8. Applies only the supplied fields and sends the complete referral back to Fours, which pushes it to AWS asynchronously APN Programs replace the full list rather than adding to it — AWS treats the field as a set. Send every program the referral should end up with. **Clearing APN Programs.** Pass an empty value (in Flow, the **Blank Value (Empty String)** resource) to remove every program. This is the only field that can be cleared — the others are left untouched when blank, because AWS either requires them or enforces a minimum length. Note the current limitation: the empty set is stored in Fours, but it does **not** yet reach AWS, so the programs can reappear on the next inbound sync. Clearing at AWS is tracked separately. Each request in a Flow collection gets its own result, so one bad row does not stop the others. --- ## Permission Requirements All Apex Actions require appropriate co-sell permissions: | Action | Required Permission | | ------ | ------------------- | | Check If Opportunity Shared | None (read-only check) | | Co-Sell | `Write_AWS_Referral`, `Write_Azure_Referral`, or `Write_GCP_Referral` (based on partner) | | Co-Sell (Fire and Forget) | `Write_AWS_Referral`, `Write_Azure_Referral`, or `Write_GCP_Referral` (based on partner) | | Process Inbound Referral | `Write_Azure_Referral` or `Write_AWS_Referral` (based on partner) | | Update Referral Linkage | `Write_AWS_Referral`, `Write_Azure_Referral`, `Write_GCP_Referral`, or `Write_Suger_Referral` (based on partner) | | Update Referral Fields | `Write_AWS_Referral` | Users with the `Create_Referral` permission have write access to all partners. --- ## Using Apex Actions in Flows To use these actions in a Salesforce Flow: 1. Add an **Action** element to your flow 2. Search for the action by its label (e.g., "Co-Sell" or "Check If Opportunity Shared") 3. Configure the input parameters 4. Store the output values in flow variables for decision logic or display ### Example Flow: Auto-Share Opportunity ```text 1. [Trigger] Opportunity Stage = "Closed Won" 2. [Action] Check If Opportunity Shared (Partner: AWS) 3. [Decision] Has Been Shared = false? - Yes → [Action] Co-Sell (Partner: AWS) - No → [End] 4. [Decision] Success = true? - Yes → [Update Record] Set custom field "AWS Referral Created" = true - No → [Create Task] "Review failed AWS co-sell submission" ``` --- ## Error Handling All actions return a `Success` boolean and `Message` string. Common error scenarios: | Error | Cause | Resolution | | ----- | ----- | ---------- | | "unsupported partner: X" | Invalid partner value | Use `AWS`, `AZURE`, or `GCP` — plus `SUGER` on Update Referral Linkage. Match the spelling exactly: only Update Referral Linkage and Update AWS Referral normalize the case for you | | "opportunityId or accountId is required" | Update Referral Linkage called with both IDs empty | Supply an Opportunity ID, an Account ID, or both | | "only AWS and Azure are supported" | Using Process Inbound with a partner other than `AZURE` or `AWS` | Use `AZURE` or `AWS`, or process through the partner portal | | "Engagement invitation not found" | Process Inbound on an AWS referral that is not an inbound engagement invitation | Only AWS-originated inbound referrals carry an invitation to accept | | "Engagement invitation is not pending, current status: X" | The AWS invitation was already accepted, rejected or has expired | Nothing to do — check the referral's current state in Fours | | Permission denied | User lacks required custom permission | Assign appropriate permission set | | "Referral not found" | Invalid referral ID | Verify the Fours referral ID is correct | | "No response from Suger" | API connectivity issue | Check Fours integration status | | "No fields supplied. Set at least one of: …" | Update Referral Fields called with every field empty | Set at least one field; a blank string counts as empty | | "Not a valid value for APN Programs: X" | A program name not on the AWS APN Program picklist | Use the picklist values exactly; the whole update is refused, nothing was sent | | "… must be a future date" / "… must be at least/most N characters" | A value Fours would silently drop or truncate | Fix the value; nothing was sent | | "Opportunity is Launched. AWS does not accept updates after close…" | Referral is Launched or Closed Lost | No update is possible after close | | "… failed to create (status CREATE_FAILED) and cannot be edited via update …" | Update AWS Referral was called on a referral whose creation failed (`CREATE_FAILED`); Fours refuses updates to it | Resubmit the referral instead: open it in Salesforce and use **Re-submit** on its detail page, which sends it through create again under the same referral ID | :::tip Always check the `Success` output before proceeding with downstream logic. Store the `Message` output for debugging failed operations. ::: --- Source: https://doc.fours.com/salesforce-app/salesforce-app-quick-actions/ # Quick Actions To streamline sales workflows, you can add **Fours Quick Actions** directly to Salesforce record pages. These buttons allow users to create offers or initiate co-sell referrals immediately without navigating away from the record. --- ## Available Quick Actions Fours provides the following standard quick actions: | Action Label | Description | | ------------------------------------- | ------------------------------------------------------------------------ | | New Offer via Suger | Create a new marketplace offer | | New Amendment Offer via Suger | Create an amendment offer against an existing agreement (AWS, Azure, GCP) | | New Resale Authorization via Suger | Create a reseller authorization (CPPO out) for a channel partner | | Co-Sell via Suger | Initiate a co-sell referral (select partner) | | Co-Sell with AWS (Suger) | Initiate an AWS co-sell referral | | Co-Sell with Azure (Suger) | Initiate an Azure co-sell referral | | Co-Sell with GCP (Suger) | Initiate a GCP co-sell referral | :::note Use the labels exactly as they appear above when you search the **Mobile & Lightning Actions** palette — those are the labels the managed package ships. **New Resale Authorization via Suger** opens the same reseller-authorization flow described in [Create Reseller Authorization](/salesforce-app/salesforce-app-cppo/). ::: --- ## Adding Quick Actions to Record Pages Adding Fours Quick Actions to Salesforce record pages (e.g., Opportunity) is a two-step process: first add the actions to the Page Layout, then arrange them on the record page. ### Step 1: Add Quick Actions to Page Layout 1. Click the **Gear Icon (⚙️) > Setup**. 1. In the Quick Find box, type `Object Manager` and select it. 1. Select the object you want to add quick actions to (e.g., **Opportunity**). 1. Click **Page Layouts** in the left sidebar. 1. Select the page layout you want to modify. 1. Scroll down to the **Mobile & Lightning Actions** section. :::note If you see the message: *"Actions in this section are predefined by Salesforce. You can override the predefined actions to set a customized list of actions on Lightning Experience and mobile app pages that use this layout."* — click the **override the predefined actions** link to enable customization. ::: 7. From the palette at the top, select **Mobile & Lightning Actions**. 1. Drag the desired Fours quick actions (e.g., "New Offer via Suger", "Co-Sell with AWS (Suger)") into the **Mobile & Lightning Actions** section. 1. Click **Save**. ### Step 2: Arrange Actions on the Record Page 1. Navigate to a record page (e.g., an Opportunity record). 1. Click the **Gear Icon (⚙️) > Edit Page**. 1. Click on the **Highlights Panel** component at the top of the canvas to select it. 1. In the right-hand properties panel, locate the **Actions** section. 1. From the palette, drag the Fours quick actions to arrange them in your preferred order. 1. Click **Save** and **Activate** to apply changes to your users. > Arranging Suger quick actions on the Highlights Panel --- Source: https://doc.fours.com/salesforce-app/salesforce-app-offer/ # Create and manage a private offer Easily create private offers from Salesforce opportunities using the Fours App within your Salesforce Console, then manage them — extend, cancel, notify contacts, or download the EULA — without leaving Salesforce. --- ## Overview A private offer is a custom deal you send to a specific buyer through a cloud marketplace — AWS, Azure, or GCP. It includes your negotiated pricing, contract terms, and expiration date. Think of it as sending a quote: once the buyer accepts it, the contract is live and billing starts automatically through the marketplace. After adding the Fours App to your Salesforce Console, you can create these private offers directly from opportunities — no need to switch to the Fours Console. You can also create Agreement-Based Offers (ABO) from Salesforce. Once an offer has been created, you can manage it from the same **Fours Widget** on the opportunity — extend the expiry date, cancel it, notify contacts, and download the EULA file. ## Prerequisites - The Fours App must be installed, connected, and set up with the Fours widget on your opportunity pages. - You need the **Suger User**, **Suger User - Marketplace**, or a cloud-specific marketplace permission set assigned to your Salesforce account. If you can't see the **New Offer** button on an opportunity, your permission set is likely missing or incorrect — see [Permission Sets](/salesforce-app/salesforce-app-permission-sets/). - The product you want to create an offer for must already exist in Fours. If it doesn't, create it in the Fours Console first before continuing. ## Create a private offer 1. Navigate to the opportunity's detail page and click the **New Offer** dropdown button at the top of the Fours App. If you don't see the widget, it may not be added to your page layout yet — see [Add Fours widgets and buttons to Salesforce pages](/salesforce-app/salesforce-app-page-components/). > New Offer dropdown button on a Salesforce opportunity 2. Locate and click the **"Private Offer"** button. > Private Offer option in the New Offer dropdown menu 3. Choose the product on which the private offer will be based and complete the required fields in the form. Note that the required fields may vary depending on the cloud marketplace and the type of offer. - The product list shows only the products available in your Fours account. - If you are assigned a cloud-specific permission set (for example, Suger Marketplace - AWS), you will only see products for that cloud. > Private offer creation form in Salesforce :::tip If field mapping has been configured, the form will be prefilled with corresponding fields from the Salesforce opportunity, making the offer creation process faster and easier. Review the prefilled values for accuracy before submitting. ::: 4. Once all necessary information is filled in, submit the form to create the offer. > Submitting the completed private offer form 5. You are all set! ### AWS offer sets An AWS offer set bundles several private offers that share the same buyer, expiry date, and customer note. **New Offer** → **Offer Set** appears in the widget once your admin turns on **Enable Offer Set in Opportunity Layout** in the settings of the **Suger** tab. 1. Click **New Offer** → **Offer Set**. The **Create Offer Set** dialog opens. 2. Fill in the shared details: **Offer Set Name**, **Customer Note**, **Buyer (AWS Account ID)**, and **Expiry Date**. You can also link an **Opportunity** and enter a **Solution Association (optional)**. 3. Under **Private Offers** — *Add 2-10 private offers to create an offer set* — click **Create Private Offer** for each offer. The private offer form opens with the set's buyer and expiry date already filled in, so enter both before you add an offer. 4. Click **Create Offer Set**. A set holds **2 to 10** offers. Once it has ten, **Create Private Offer** is disabled with the tooltip *Maximum of 10 offers reached*. With fewer than two, **Create Offer Set** is disabled with the tooltip *Please add at least 2 offers*. :::warning AWS's own documentation still sets an offer set at 2 to 7 offers: its Catalog API answers `TOO_MANY_OFFERS` (*Associate up to 7 offers to the offer set*) for more, and AWS has not published a higher limit ([Work with offer sets](https://docs.aws.amazon.com/marketplace/latest/developerguide/work-with-offer-sets.html)). Fours lets you add up to 10. Confirm with your AWS contact before you release a set of more than 7. ::: ### If the product's pricing could not be loaded The **AWS**, **AWS Container**, and **GCP** create forms show a red banner at the top when Fours could not load the selected product's specification. Submitting is refused with: > Cannot create this offer: the product info could not be loaded. *{detail}* A related message appears when the product loaded but has no pricing plans to choose from: > Please select a pricing plan. If the dropdown is empty, this product's pricing could not be loaded. Both mean the same thing in practice: pick a different product, or fix the product's pricing in the Fours Console, then reopen the form. There is no field on the form to correct. ### GCP prepay: what happens to unused commitment A **GCP prepay** offer's create form carries an **Unused commitment rule** selector above the installment schedule, with three choices: | Rule | What it does | | --- | --- | | **Rollover** | An installment's unused balance carries into the next installment. | | **Expire** | The unused balance is discarded at the end of the installment — the carried-over commitment **and** any partner-sponsored free credit. | | **Custom** | Set the behaviour installment by installment. | Once the offer exists, the installment table on the offer detail page shows the resulting rule as a read-only **Unused Commitment** column, worded exactly as the GCP producer portal words it, so the two can be compared side by side: - **Rollover to next commitment** - **Expire all unused balance** - **Expire all at offer end date** — the final installment, where the term ends and nothing can roll further. ### GCP usage pricing models When the plan you select is a GCP usage plan, the form asks for a **Usage Pricing Model**. Each choice shows, beneath it, the hint GCP's Producer Portal gives for it: | Usage Pricing Model | Hint shown beneath it | | --- | --- | | **Commitment discount with additional usage at list price** | *The customer promises to pay a discounted amount. All usage, including overages, is list price.* | | **Commitment with all usage discounted** | *The customer promises to pay an amount. All usage, including overages, is discounted.* | | **Usage-based discount only** | *The customer pays a discounted amount for what they use* | On a **replacement** offer the model is filled in from the offer being replaced — prepay offers and offers created in GCP's Producer Portal included. Keep it: GCP refuses a replacement offer that changes the usage pricing model. The one exception is a replacement opened from a Salesforce record whose [private offer field mapping](#configure-crm-field-mapping-for-private-offers) sets a model. If the mapped value is one of `CUD_LIST_PRICE`, `CUD_ALL_USAGE_DISCOUNTED` or `USAGE_DISCOUNT_ONLY` and differs from the replaced offer's, the form opens with the mapped model instead — a label such as *Usage-based discount only* is ignored. A mapped model also resets **Payment Recurrence** to match, and **Commitment discount with additional usage at list price** clears the discounts carried over from the replaced offer, since that model prices usage at list price. Because GCP refuses a changed model, check a mapped model against the replaced offer before you submit. ### Proration (GCP, monthly billing) A GCP private offer — on the plain private offer form or the **GCP Professional Services** form — whose **Payment Recurrence** is **Monthly** has a **Proration** switch in its pricing section: | Setting | What GCP does | | ------- | ------------- | | **Off** (the default) | Installments follow the offer's anniversary date. | | **On** | GCP prorates the first installment against the start date, so billing lines up with calendar months. | The switch appears only for **Monthly** recurrence, and never when the usage pricing model is **Usage-based discount only**, which has no commitment installment to prorate. ### Auto Renew (GCP) On the GCP private offer, **GCP Professional Services**, and replacement forms, the pricing section has an **Auto Renew** switch. Turned **On**, it lets the customer decide whether the contract's pricing and terms auto-renew, and a required **Number of renewals** field appears beside it, starting at **1** — the number of times the customer can renew on the current term, unless an amendment is accepted. Turning the switch **Off** removes the count. - The count is a whole number of at least 1. - GCP caps an offer's first term plus every renewal at **84 months**, so the most renewals allowed are (84 − term) ÷ term, rounded down, with the term in months. The **Offer Duration** is entered in the **Payment Recurrence**'s own unit, so a duration of 4 on a **Quarterly** offer is a 12-month term. A 12-month term allows 6 renewals and a 24-month term allows 2. A term longer than 42 months cannot auto-renew. - An offer on a **Custom** installment schedule never renews, so it has no count. - A clone or a replacement starts with the original offer's count, and an auto-renew offer saved before the count existed shows 1. The form shows the problem under the field, and refuses to create the offer until it is fixed: | Message | What it means | | ------- | ------------- | | *Please enter the number of renewals.* | The field is empty. | | *The number of renewals must be a whole number of at least 1.* | The value is zero, negative, or a fraction. | | *A {n}-month offer can't auto-renew. Shorten the duration to 42 months or less, or turn off auto-renew.* | The term is longer than 42 months. | | *Maximum number of renewals allowed based on the offer duration is {max}.* | The count is more than the term allows. | ### AWS net payment terms For an AWS private offer, choose **Customer's net terms with AWS** to leave the custom term empty, or choose Net 15, 30, 45, 60, 90, or 120 after agreeing the term with the buyer. The buyer does not choose this value in Fours. Agreement-Based Offers are treated as new offers, so this selection starts empty. For a CPPO resale authorization, the ISV selects the **maximum** buyer net payment term. For the downstream CPPO, the channel partner can inherit that maximum or select a shorter term, but cannot select a longer one. If the authorization has no maximum, a custom downstream term is unavailable. Cloning any supported AWS offer or authorization copies its current value into the new-offer form. Released values are read-only. :::warning **Wait 3–5 minutes before copying the offer link.** Fours sends the offer data to the cloud marketplace immediately, but the marketplace takes a few minutes to process it. The **Copy Offer URL** button on the offer record won't work until the offer is fully created on the marketplace side. Refresh the page after a few minutes and the URL will be ready. ::: ### Configure renewal terms (AWS) AWS contract offers can carry **pre-authorized renewal terms**, so the agreement renews on terms the buyer already agreed to instead of requiring a new offer each cycle. When the offer qualifies, a **Configure renewal terms** section appears on the AWS offer form. Whether the section appears depends on the product's **commits**. It is not a setting you can turn on, and usage dimensions on the same product do not hide it: | Offer form | The section appears when | | ---------- | ------------------------ | | **AWS SaaS** | The product carries at least one commit. | | **AWS Container** | The product carries at least one commit, and the offer is priced with commits — not usage-only, and not free. | | **AWS AMI** | Never. An AMI offer cannot carry renewal terms, so the section is not shown whatever the product's pricing. | | **AWS Professional Services** | The product carries at least one commit. | If the offer stops qualifying after you set renewal terms — for example, you switch to a product with no commits — the terms are removed from the offer automatically, so they are never sent to AWS on an offer that cannot carry them. Pick one of three renewal options: | Option | What it does | | ------ | ------------ | | **No price uplift** | Renew at the same price each cycle. | | **Price uplift** | Increase pricing by a fixed percentage, or within a pre-negotiated range, each cycle. | | **No renewal** | Do not include auto-renewal terms with this offer. | Choosing **Price uplift** reveals a **Price uplift type**: | Uplift type | Fields | | ----------- | ------ | | **Fixed percentage** | **Price increase percentage** — 0 to 100, in steps of 0.01. | | **Percentage range** | **Minimum uplift percentage**, **Maximum uplift percentage**, and **Default uplift percentage**, each 0 to 100 in steps of 0.01, plus an **Adjustment deadline** — the number of days before agreement expiration by which you must settle the uplift. The final figure inside the range is chosen later, per renewal. | Selecting **No price uplift** or **Price uplift** opens that option's card, and both carry the same three settings: | Setting | What it does | | ------- | ------------ | | **Renewal decision deadline (optional)** | The number of days before the agreement expires after which neither party can opt out of the renewal. Leave it blank to use the agreement expiration date itself. The deadline must fall inside the contract term; if it does not, the form names the date it lands on and the term it misses, for example *Renewal decision deadline (800 days) falls on 2025-07-23, which is not inside the contract term (2026-10-01 → 2027-10-01).* A percentage range's **Adjustment deadline** is checked the same way. | | **Renewal count** | **Definite** renews a set **Number of renewals**; **Indefinite** keeps renewing. | | **Renewal payment schedule** | Optional. Turn on **Enable renewal payment schedule** to invoice each renewal cycle in installments — up to **86**, totaling 100%. | **The schedule starts from your offer's own installments.** When you turn the schedule on, each of the offer's **Payment Installments** becomes a row carrying its share of the total; installments on the same date merge into one row. The offer's start date begins month 0, and each month runs from that day of the month: with an October 15 start, a November 1 installment is still in month 0, so twelve monthly installments from November 1 run months 0 to 11. When the offer has no start date, or an installment falls before it, the earliest installment is month 0 and later rows count calendar months from it. Rows are counted in months, each keeping its own day of the month (except the agreement's last month — see below), unless two installments fall in the same month — then the whole schedule is counted in exact days. The rows follow the offer's installments until you edit them; after that they are yours. An offer with no installments starts with a single 100% row. To lay out a schedule yourself, click **Renewal Payment Scheduler**: choose a **Payment frequency** (Monthly, Quarterly, Semi-annually, Annually, or Custom), a **Due date calculation** (**By month** or **By exact days**), the **Number of installments**, and optionally a **Day of month**, check the **Plan preview**, and click **Create**. **New payment installment** adds a single row. Each row has its offset — the column reads **Months after agreement start** or **Days after agreement start** — an optional **Day of month**, and a **Percentage of TCV**, and the footer shows how much is **Allocated** and **Remaining**. When the offer has priced payment installments, the schedule also states the **Original contract total** and **Contract duration**, and each row shows an **Estimated first renewal cycle payment amount** — its share of the contract total after one cycle of uplift. **The last month bills on the renewal start day.** AWS does not accept a custom billing day on the installment in the agreement's final month. When the contract term is set in months or years, that row's **Day of month** is locked: it reads **Start day**, and its help icon explains *AWS bills the last installment on the same day of the month the renewal starts. A custom day isn't allowed for the last month.* A day on that row is dropped however it got there — seeded from your installments, laid out by the scheduler, or typed in. The scheduler's **Day of month (optional)** field carries the help text *Optional. The last month always bills on the renewal start day.*, and the **Plan preview** labels that row, for example *Month 11 of the agreement, renewal start day*. A row counted in months can't fall after that month: Fours refuses the offer when you click **Create**, and the **Failed to create offer** message includes the row's offset, for example *AWS renewal schedule entry "P12M" is past the last month of the renewal agreement (a term of this length has offsets P0M to P11M)*. When the offer has an explicit end date, or a term in days or weeks, every row keeps its own editable billing day. Once the offer exists, the terms read back as a **Renewal terms** card on the offer detail page. Managing a renewal *after* the buyer accepts — adjusting the uplift inside an agreed range, or opting out — happens on the entitlement, not here; see [pre-authorized auto-renewal](/aws-marketplace/pre-authorized-auto-renewal/). ### Auto-Activation (Azure) Azure SaaS offers can carry an **Auto-Activation** toggle — *Automatically activate the subscription on purchase*: - **On** — Azure activates the SaaS subscription automatically once the customer purchases the private offer. - **Off** — your team activates the subscription. **Fours does not activate it for you** on these integrations, because the integration manages subscription activation itself. The toggle appears only when both are true: the Azure integration is set to **self-managed subscription activation**, and the offer uses **V2 pricing** (`newCustomizedPlans`). V1 offers cannot carry the setting at all, so it is hidden rather than shown disabled. ### Notification contacts on an Azure offer On an Azure private offer, the people you select in the form's **Notification Contacts** section are saved as the offer's Fours contacts — the same list the **Notification Contacts** card shows once the offer exists (see [Notify contacts](#notify-contacts)). They are no longer sent to Microsoft as the Azure offer's own notification contacts; Fours emails them only through the **Offer Notification Contacts** rule in your [email notification settings](/settings/email-notification/#email-an-offers-contacts). ### Attach your own EULA files When the offer uses your own EULA, the form's **EULA** section lists every PDF you attach, and Fours merges them into one document **in the order shown**. Use the arrows beside each file — **Move up in merge order** and **Move down in merge order** — to change its position before you submit. - If you also tick **Attach Standard Contract for … Marketplace**, or the checkbox that attaches your public offer's default EULA, that document is appended **last**, after your own files. - On an **Agreement-Based Offer** that uses **Append to Existing EULA**, the base agreement's existing EULA stays **first**, and the files you upload follow it in the order shown. - The **AWS Reseller** and **AWS Professional Services** forms have no standard contract to attach, so their files merge in the order shown. #### Choose PDFs from a related record Besides uploading a file, the **EULA** section can pull PDFs that are already in Salesforce: **Select from Opportunity Attachments**, and **Select from Quote Attachments** when the offer is tied to a Quote. It adds at most one more button, for the record you started the offer from: - **When your admin has set a lookup for that record's object** — a record your starting record looks up to, such as an Agreement a Quote points at — the button reads **Select from *{lookup field}* files** and lists the Salesforce Files attached to that related record. - **Otherwise** — no lookup set, or one set for a different object — the button reads **Select from *{object}* files**, for example **Select from Agreement files**, and lists the files on the record you started from. Each record's files are offered once: when the extra button would open the same Opportunity or Quote as **Select from Opportunity Attachments** or **Select from Quote Attachments**, it is left out. An offer started from an Opportunity therefore shows no extra button unless your admin's lookup leads to a different record. ```d2 direction: right start: "Record you start the offer from" related: "Related record\nfor example an Agreement\na Quote points at" files: "Its Salesforce Files" own: "The starting record's own files\nfor example an Agreement\nyou start from" eula: "Offer EULA\nPDFs you pick" start -> related: "a lookup your admin\nset for this object" related -> files files -> eula: "Select from … files" start -> own: "no lookup set\nfor this object" own -> eula: "Select from … files" ``` - When the lookup on your record is empty, or points at a record you cannot see, the button is disabled with *No related record found.* - Pick one or more PDFs. The picker states the limit — **20 MB** per file on the AWS forms, **3.5 MB** on the Azure and GCP forms — and asks you to deselect anything larger. A related record with no files reads *No files available on this record.* - Fours checks your own Salesforce access to the record and the file before attaching it, so you can attach only what you could open yourself. - The files join the EULA list like any upload and merge in the order shown. The button is on the AWS (SaaS, Container and AMI, Machine Learning, and Professional Services), Azure, and GCP (private, Professional Services, and replacement) offer forms. The AWS Reseller form and the reseller authorization forms do not have it. If the button cannot be used, its message says why: | Message | What it means | | ------- | ------------- | | *No related record found.* | The lookup on the record you started from is empty, or the related record is not visible to you. | | *Unable to access this document source. Contact your Salesforce administrator.* | Salesforce refused access to the lookup or the record. | | *Document source configuration: …* | The configured lookup no longer exists on the object, or is not a direct lookup to a single object. Ask your admin to fix the setting. | | *Select a PDF within the size limit shown on the offer.* | The file you picked is not a PDF, or is over the limit. | | *The file is no longer available on this document source.* | The file was removed from the related record after the picker opened. Open the picker again. | ### Snowflake: attach PDFs for the buyer A Snowflake private offer has an **Attachments** section for PDF files the customer can download while viewing the offer — up to **5** files, **5 MB** each. 1. Click **Attach file** to add a row, then choose a PDF for it. 2. Repeat for up to five files. **Attach file** disappears once five rows exist, and the trash icon on a row removes it. A file over 5 MB is refused with *The file size is too large.*, and a file that is not a PDF with *The file type is not supported.* Once the offer exists, the offer page lists the attached file names under **Attachments**. ### Oracle: when billing starts An Oracle private offer sets when billing starts in its **Billing Start** section: | Option | What happens | | ------ | ------------ | | **On acceptance** (the default) | Billing starts when the buyer accepts the offer. | | **Specify date** | A date field appears, and billing starts on the date you pick. | **Offer Expiration Date** — the buyer's deadline to accept — defaults to 30 days after creation, or to the day before the billing start date if that is sooner. When you specify a start date, the expiration date must fall before it. The form refuses to submit with: - *Billing start date is required when billing starts on a specific date.* - *Offer expiration (accept-by) date must be before the billing start date.* ### What happens next After you submit the offer: - Fours creates the offer record in your Salesforce org, linked to the opportunity. - The offer is sent to the cloud marketplace (AWS, Azure, or GCP) for processing. - Once the marketplace confirms the offer, the offer status updates and the offer URL becomes available. - You can then copy the offer URL from the offer record and send it to the buyer — they use it to review and accept the offer in their cloud marketplace account. :::tip For best practices, a full field breakdown, and the complete private offer lifecycle, see [Private Offer Best Practices](/aws-marketplace/offer-best-practices/). ::: ## Track private offer status After creating a private offer, you can track its progress directly from the Opportunity page via the embedded Fours widget. All offer and entitlement data synced from the marketplace is displayed in real time within the widget — no need to switch platforms. 1. Once you click **Create**, you're returned to the Opportunity detail page. The Fours widget immediately displays the new offer with the status **`PENDING_CREATE`**. ![Suger widget showing a new offer in PENDING_CREATE status](images/creating-a-private-offer-in-salesforce-5.png) 2. Wait up to **5 minutes**, then refresh the widget. The offer status updates to one of the following: - **`Create Success`** — the offer was successfully created in the marketplace but has **not yet been sent** to the buyer. - **`Pending Acceptance`** — the offer has been **pushed to the marketplace** and the buyer has been notified. ![Suger widget showing updated offer status](images/creating-a-private-offer-in-salesforce-6.png) - **`Create Failed`** — Fours could not complete the offer's creation on the marketplace. The marketplace may have refused it **before anything was created** — its shape, term, or replacement target was rejected pre-flight — or the create may have failed partway through and left something behind. Open the offer: the error Fours recorded, when there is one, is shown on the offer page. If **Edit Draft** is offered, use it to correct the offer and submit it again. Offers refused pre-flight in the past may show **`Invalid`** instead; to try again, **Clone** the offer and create the copy. 3. When the buyer accepts the offer, the widget updates to show **`Accepted`**, and you'll see the corresponding **Offer object** linked within the widget. ![Suger widget showing an accepted offer linked to the Offer object](images/creating-a-private-offer-in-salesforce-7.png) 4. Click the offer directly in the widget to open a detailed view, including pricing, contact information, term details, and entitlement data. ## What's on the offer detail page Beyond the standard offer fields, the offer detail page shows a few sections only when they apply to that offer. If you don't see one below, it means the condition for it wasn't met — not that data is missing. ### Buyer payment term (AWS) **AWS** offers carry a **Buyer payment term** row in **Offer Information**, showing the term as its friendly label (*Net 30*) rather than its raw duration. On a **reseller authorization or CPPO** — inbound or outbound — the same row is relabelled **Maximum buyer net payment term**, because on those the value is the ceiling the ISV set rather than the term the buyer actually gets. The row is hidden on non-AWS offers, and on an AWS offer where the buyer is using their AWS account default, so it never renders as a bare dash. ### Renewal offers (AWS and Azure) An offer is recognized as renewing an existing agreement on both AWS and Azure — AWS marks it on the offer's metadata, Azure through the private offer's customer contract renewal flag. Whichever cloud it came from, the offer reads as a renewal wherever the app shows renewal status. ### Replaced Offer ID and Replaced Offer (GCP) **GCP** replacement and amendment offers carry two extra rows in **Offer Information**, so you can trace the new offer back to the one it supersedes: | Row | What it shows | | --- | ------------- | | **Replaced Offer ID** | The marketplace ID of the offer this one replaces. | | **Replaced Offer** | A link straight to the replaced offer's record in Salesforce. | Both rows appear only on GCP replacement and amendment offers. **Replaced Offer** is additionally omitted until Fours has resolved the replaced offer into a record it can link to — if you see the ID but not the link, the replaced offer hasn't synced yet. ### GCP dates in Pacific time GCP's Producer Portal shows a private offer's dates on the Pacific clock, and so does the offer page. On a **GCP** offer, dates read as a Pacific date and time with the **PST** or **PDT** label — for example `8/31/2026, 11:45:00 PM PDT` — so everyone sees the same value whatever their own timezone. | Row | What it shows | | --- | ------------- | | **Expire Date** | 11:45 PM Pacific on the last day the buyer can accept — the time GCP itself displays. | | **Acceptance Date** | When the buyer accepted. | | **Start Date**, **End Date** | GCP only: the offer's term start and end. Each row is hidden until the offer has that value — a pending offer may have no start yet, and a pay-as-you-go offer has no end. | Offers on other marketplaces keep showing the date alone. ### Note for Buyer (GCP) - A **GCP** offer that carries a note for the buyer shows a **Note for Buyer** row in **Offer Information**. It is hidden on non-GCP offers, and on a GCP offer that has no note, so it never renders empty. ### Universal PAYG discount banner When a GCP offer was priced with a single discount across all usage rather than per-dimension rates, a banner sits at the top of **Offer Information** stating the discount — for example, **20% off all usage**, captioned *Universal PAYG discount*. It is there so a reviewer doesn't read the absence of a per-dimension breakdown as missing pricing. ### Dimension Tags (read-only) If your organization uses **dimension tagging** to build discounts (see [Dimension-tag discounts](#dimension-tag-discounts-gcp-aws-azure) below), the offer detail page shows the tag configuration the offer was built with, as a read-only **Dimension Tags** section directly above the pricing section. You cannot edit it here — this is the record of how the offer was priced. | Cloud | Where it appears | | ----- | ---------------- | | **AWS** | One panel at the offer level, above **Usage Dimensions**. | | **GCP** | One panel at the offer level, above **Usage Dimensions**. For **prepay** offers, tag groups are set per payment installment, so you get one panel per installment. | | **Azure** | One panel **per plan**, above **Azure Pricing** — matching the way Azure offers configure discounts per plan. A plan with no dimensions shows nothing. | :::note The section only renders when your org has dimension tagging enabled, the offer is priced in **USD**, and the offer actually used a configured tag group. An offer priced dimension-by-dimension by hand has no Dimension Tags section. ::: ## Clone a private offer You can quickly create a new offer based on an existing one. 1. Open the **Opportunity** that contains the existing offer. 2. In the **Fours widget**, click the offer you want to clone. 3. In the top-right corner of the offer view, locate the **arrow-down button** next to the **Refresh** icon. 4. Click the dropdown and select **Clone**. 5. A new offer form opens with pre-filled details from the original offer. Make any necessary changes and click **Create** to submit. ![Cloning a private offer from the Suger widget in Salesforce](images/how-to-clone-a-private-offer-in-salesfor-1.gif) :::note **Clone is not offered on every offer.** Reseller authorizations and the resale offers made under them (`CPPO` and `CPPO_IN`) cannot be cloned — a CPPO is reseller-owned and an inbound resale authorization is a read-only object the provider synchronizes. Agreement-Based Offers cannot be cloned either, because the agreement details are not carried into the copy. ::: **What a GCP clone copies.** Cloning a GCP private offer carries the original's negotiated terms into the new form — customer and provider details, notes, deal type, payment recurrence and schedule, duration, features, and proration setting — including when the original was created in GCP's Producer Portal. The original's error messages, notifications, acceptance date, and marketplace-side offer identity are cleared, so a clone of a failed offer opens without the original's error. A resale authorization (`CPPO_OUT`) is cloned through the resale-authorization form instead, and this cleanup does not apply to it. :::tip For steps on canceling, extending, notifying contacts, and more, see [Private Offers](/console/private-offers/). ::: ### GCP replacement offers: term and cancellation Cloning a **GCP** offer produces a replacement offer, and its form carries two controls that decide how the new offer relates to the one it replaces. 1. **Change Offer Duration** — a toggle whose own help text reads: *"Off keeps the replaced offer's end time (coterm). Turn on to set your own term via Offer Duration."* - **Off** (the default) — the replacement **coterms** to the replaced offer: it ends on the same date, and the form shows that date as a read-only **Offer End Date**. - **On** — an **Offer Duration** field appears and you set the term yourself. Its unit follows the **Payment Recurrence** you selected. 2. **Cancel the existing offer at the publishing of this offer** — a checkbox in the **Existing offer** card. When checked, the original offer is cancelled automatically once the new offer reaches **pending acceptance** status. This only affects whether the original offer is still visible and acceptable; it does **not** touch an existing subscription if the buyer had already accepted the original offer. On a **Monthly** replacement offer, the [Proration](#proration-gcp-monthly-billing) switch is shown read-only. GCP does not allow the proration policy to change on an amendment, so the form carries over the replaced offer's setting: **On**, **Off**, or **Not set (GCP default)** when GCP created the original offer under its own default. **A replacement needs an offer GCP still considers live.** If GCP shows the offer you are amending as ended — expired, cancelled, lapsed, or failed approval — Fours refuses the replacement when you click **Create**, with an **Invalid offer** message: *The offer you are amending ({offer ID}) has already ended on GCP and can no longer be replaced. If this buyer has an active successor offer for the same billing account, amend that one instead — otherwise create a new offer.* While GCP is still settling the offer's state, the message names it instead, for example *… is in state OFFER_EXPIRED on GCP and can no longer be replaced. …* An entitlement that is **pending cancellation** is the exception: its offer has run its term, but you can still amend it. ## Manage an existing offer Once a private offer has been created from an opportunity, you can manage it without leaving Salesforce. Open the **Opportunity** that contains the offer, then click the offer in the **Fours Widget** to open the Offer Page. From there you can extend the expiry date, cancel the offer, notify contacts, and download the EULA file. :::tip For steps on canceling, cloning, extending, notifying contacts, and more, see the full [Private Offers](/console/private-offers/) guide in the Fours Console. ::: ### Extend a private offer **Extend Expiry Date** is offered only where the marketplace accepts the change, so the action is absent rather than failing: | Marketplace | Can extend? | | ----------- | ----------- | | **AWS** | Yes — except a **resale authorization (CPPO_OUT)**. AWS rejects any change to a released resale authorization. | | **Azure** | Only on **V2 / V3 pricing** (`newCustomizedPlans`, `saasNewCustomizedPlans`, `vmSoftwareReservations`). Not on V1. | | **Oracle** | No — Oracle Marketplace does not support extending an offer's expiry date. | | **GCP and the rest** | Yes. | The offer must also be in **Pending acceptance**, **Expired**, or **Update failed**. An offer the buyer has already accepted has an agreement behind it, and its expiry date no longer governs anything. 1. Open the **Opportunity** that contains the private offer. 2. In the **Fours Widget**, click the offer you want to extend. 3. Click the **arrow-down button** next to the **Refresh** icon in the top-right corner. 4. Select **Extend Expiry Date** from the dropdown menu. 5. Update the **Expiry Date** to a new future date, then save. ![Extending a private offer from the Suger widget in Salesforce](images/how-to-extend-a-private-offer-in-salesfo-1.gif) ### Cancel a private offer 1. Open the **Opportunity** that contains the private offer. 2. In the **Fours Widget**, click the offer you want to cancel. 3. Click the **arrow-down button** next to the **Refresh** icon in the top-right corner. 4. Select **Cancel Offer** from the dropdown menu. 5. Confirm the cancellation when prompted. ![Canceling a private offer from the Suger widget in Salesforce](images/how-to-cancel-a-private-offer-in-salesfo-1.gif) ### Notify contacts 1. Open the **Opportunity** that contains the private offer. 2. In the **Fours Widget**, click the offer you want to notify contacts about. 3. Find the **Notification Contacts** card on the right side of the Offer Page. 4. Click **Add Contact**. 5. Choose the contact(s) you want to notify and confirm. The picker opens on **Create Offer Contact**, where you type a new person's name and email; to pick someone who already exists, switch to **Salesforce Contacts**, **Salesforce Users**, or **Suger Platform Contacts**. ![Adding notification contacts to an offer in Salesforce](images/how-to-notify-contacts-in-salesforce-1.gif) Whether Fours' notification email actually goes out is decided by your organization's email notification settings in the Fours console: it is sent only while **Enable Email Notification** is on and the **Notify offer contacts** row is enabled, and the contacts you pick reach it through that row's **Offer Notification Contacts** rule. See [Notify contacts](/console/private-offers/#notify-contacts). ### Download the EULA file 1. Open the **Opportunity** that contains the private offer. 2. In the **Fours Widget**, click the offer you want to review. 3. Scroll down to the bottom of the Offer Page. 4. The **EULA** file is available in the last section of the Offer Page. ![Downloading the EULA file from an offer in Salesforce](images/how-to-download-the-eula-file-in-salesfo-1.gif) Once an offer is past **Draft**, clicking its EULA opens the file in a new browser tab. Fours fetches a current download link at the moment you click, rather than reusing the link saved on the offer, which can expire — so allow pop-ups for Salesforce. If the file cannot be opened, an **Unable to open EULA** message gives the reason: *Allow popups for Salesforce, then try again.* when the browser blocked the new tab, *The EULA download link is unavailable. Please try again.* when Fours returned no usable link, or the error Fours reported. ## Configure CRM field mapping for private offers Configuring Salesforce private offer field mapping lets you auto-generate private offer fields from your CRM, so information is pre-populated when sending offers from Salesforce. This saves time and reduces manual entry errors during deal submission. Field mapping is set up in the Fours Console by your Salesforce admin. 1. **Access the Fours Console** — the central hub for managing configurations and settings. 2. **Open Offer, then the page's Settings tab.** 3. **Select the CRM sub-tab.** 4. **Click New Config in the Salesforce block.** 5. **Choose the Cloud partner and associated CRM** for which you want to configure the field mapping. 6. **Map Salesforce fields** to the fields relevant to private offers. For example, associate offer names with opportunities, the buyer AWS account ID with the corresponding field, and offer expiration dates with the relevant fields. 7. **Save the configuration.** ### Skip the entitlement picker on an amendment **New Offer** → **Amendment Offer** (and the **New Amendment Offer via Suger** quick action) normally opens the **Create Amendment Offer** dialog so you can pick the entitlement to amend from its **Suggested** list. The list leaves out entitlements for products you couldn't choose on a new offer from the same opportunity or quote, such as a product your organization's [List Products Filter](/settings/private-offer-mapping/#step-3-set-listing-filters-optional) excludes. To skip that step, map `metaInfo.baseEntitlementExternalId` in your private offer field mapping to a Salesforce field that holds the entitlement's marketplace ID — for example `Suger__Entitlement_External_ID__c`. The form then opens straight on the AWS agreement-based offer, Azure upgrade offer, or GCP replacement offer for that entitlement. Only the mapping for the cloud your **Cloud Partner Selection** script returns counts. If the mapped entitlement can't be found or can't be amended, a *Mapped entitlement can't be amended* warning gives the reason and the picker opens as usual. When the form opens straight on the entitlement, the amendment-offer banner naming it ends with a **Change** link that reopens the entitlement picker, so you can pick a different one — on the AWS, Azure, and GCP amendment forms. ### Add a related record as a EULA source The **Salesforce** block on the same **CRM** sub-tab holds **Offer Created From** — the Salesforce object a private offer is created from and your field mapping reads, such as Opportunity or Quote — and, beneath it, an optional **EULA Document Source**. Setting it points the [Select from … files](#choose-pdfs-from-a-related-record) button at a related record instead of the record the offer is started from. 1. In the Fours Console, open **Offer**, then the **Settings** tab and its **CRM** sub-tab, and find the **Salesforce** block. 2. Check **Offer Created From** is the object your team starts offers from. 3. In **EULA Document Source**, pick one lookup field on that object. The list holds the object's direct lookups to a single other object — lookups to User are left out — and **Related object:** below it names the object the lookup points at. If a field you just created in Salesforce is missing, click the refresh icon beside the list. 4. Click **Save**. Choose **None** to remove the lookup; the offer forms then offer the files of the record the offer is started from. Changing **Offer Created From** clears it, because a lookup belongs to one object. If a saved lookup no longer exists, the block says *Configured lookup {field} is unavailable. Select another lookup or clear it.*, and an object with nothing to pick reads *No supported lookup fields on this object.* Only one direct lookup is supported. To reach an Agreement through an Opportunity's primary Quote, start offers from the Quote and configure the Quote's Agreement lookup. Changing the setting never alters the EULA files on offers you have already created. The rest of these settings are covered in [Private Offer Field Mapping](/settings/private-offer-mapping/). ### AWS private offer required fields | Field Name | Source | Description / Purpose | | --- | --- | --- | | Salesforce Opportunity ID | Salesforce Field (`Id`) | Identifies the Opportunity associated with the offer. Required for linking the private offer to the correct Salesforce record. | | Renewal Offer Type | Salesforce Field | Indicates whether the offer is new or a renewal. | | Product ID | Salesforce Field (Fours Product Id) | Maps the Fours product to the AWS listing product ID. Required for AWS to recognize which listing the offer belongs to. | | Offer Name | Expression: `{{ .Name }} - {{ .Account.Name }}` | Defines the custom name for the offer as it appears in AWS Marketplace. Usually combines Opportunity and Account names. | | Buyer AWS Account ID | Salesforce Field | The buyer's AWS Account ID — needed so AWS can associate and allow that buyer to view and accept the private offer. | | Contacts | Salesforce Field / Manual Entry | Contact names and emails of people who should be notified when the offer is ready. Can include the Opportunity owner and additional internal contacts (for example, `{{ .Owner.Name }}`, `{{ .Owner.Email }}`, or manually added users like your teammate). | | EULA Type | Salesforce Field | Specifies which End User License Agreement (EULA) to attach — for example, "Standard AWS Terms" or a custom EULA. | | Offer Expiry Date | Salesforce Field | The date before which the offer must be accepted, or it expires (format: `YYYY-MM-DD`). | | Offer End Date | Salesforce Field | The date when the offer will officially end or expire (format: `YYYY-MM-DD`). | | Start Date | Salesforce Field | The start date for the offer (by default, the acceptance date). | | Script (Optional) | Custom Script | Used to fill any remaining fields not mapped above. Optional but useful for automation or custom rules. | ## Troubleshooting | Issue | Possible cause | Resolution | | --- | --- | --- | | No **New Offer** button visible on the opportunity | Fours permission set not assigned, or the Fours widget is not on the page | Check your permission set assignment, and add the widget if it's missing. | | Product list is empty | No products have been set up in Fours, or your permission set restricts which clouds you can see | Confirm that products exist in the Fours Console. A cloud-specific permission set only shows products for that cloud. | | Form fields are blank — not pre-filled from the opportunity | Field mapping has not been configured | Field mapping is an optional admin setup. Contact your Salesforce admin to configure it. | | **Copy Offer URL** button does nothing after the offer is created | The marketplace hasn't finished processing the offer yet | Wait 3–5 minutes, then refresh the page. The URL appears once the marketplace confirms the offer. | | Offer was created but doesn't appear on the opportunity | Sync between Fours and Salesforce is delayed | Offer records sync on a schedule. Refresh after a few minutes. If it still doesn't appear, check the Fours Console to confirm the offer was created successfully. | | **Unable to open EULA** when you click an offer's EULA | The browser blocked the tab the EULA opens in, or Fours could not return a current download link | For *Allow popups for Salesforce, then try again.*, allow pop-ups for your Salesforce domain and click the EULA again. For *The EULA download link is unavailable. Please try again.*, try again in a moment, and contact support@suger.io if it keeps failing. | | **Invalid offer** — *Could not determine the offer being replaced. Reload the entitlement and try again.* — when you create a GCP replacement (amendment) offer | Fours could not tell which GCP offer the new one replaces: neither the entitlement nor its offer names it | Reload the entitlement and create the replacement again. If the message persists, contact support@suger.io. | | **Invalid offer** — *The offer you are amending (…) has already ended on GCP and can no longer be replaced.* — when you create a GCP replacement (amendment) offer | GCP shows the offer you are amending as expired, cancelled, lapsed, or failed approval | Amend the buyer's active successor offer for the same billing account, if there is one; otherwise create a new offer. See [GCP replacement offers](#gcp-replacement-offers-term-and-cancellation). | | **Failed to create offer** — *AWS renewal schedule entry "P12M" is past the last month of the renewal agreement (a term of this length has offsets P0M to P11M)* — when you create an AWS offer with renewal terms | A row of the **Renewal payment schedule** is numbered past the last month of the contract term, which runs from month 0 | Edit the schedule so its last row falls in the term's final month — month 11 on a 12-month term — then click **Create** again. See [Configure renewal terms (AWS)](#configure-renewal-terms-aws). | | The GCP offer's expiry date won't accept a date more than **3 months** out | GCP's three-month acceptance window. The GCP offer forms and the **Extend Private Offer Expiry Date** dialog now block dates more than three months out — and dates before the offer's start or end — directly in the date picker, with an inline hint, so the limit is enforced before you submit. The create API still enforces it as a backstop. | Pick an expiry date within the three-month window shown in the picker's hint. | ## Frequently asked questions **Can I create offers for AWS, Azure, and GCP from the same place?** Yes — as long as you have products set up for each cloud in Fours and the right permission set assigned. The product selector in the offer form shows products across all clouds you have access to. **Can I create an Agreement-Based Offer (ABO) from Salesforce?** Yes. Agreement-Based Offers are supported from Salesforce — you don't need to use the Fours Console for this. **What is field mapping and do I need it?** Field mapping is an optional configuration that automatically pre-fills offer form fields with data from the Salesforce opportunity — like buyer name, contract value, or close date. Your Salesforce admin sets this up. You can still create offers without it, but you'll need to fill in all fields manually. **The offer was created successfully but the buyer can't find the link. What do I do?** Open the offer record in Salesforce and click **Copy Offer URL**, then send that link directly to the buyer. Make sure at least 3–5 minutes have passed since the offer was created, otherwise the URL may not be available yet. **Will the offer show up in the Fours Console too?** Yes. Any offer created from Salesforce is also visible in the Fours Console under your offers list. ## Dimension-tag discounts (GCP, AWS, Azure) When your organization has **dimension tagging** enabled (configured in the Fours web console), the discount step of a private offer shows a tag-based discount panel in place of the per-dimension rate table, for **GCP**, **AWS**, and **Azure** offers: - **Build a rule** from tag conditions (e.g. `region` contains `us-east`) and apply one discount to every matching dimension at once. - **Apply a saved discount group** from your org library, then set its discount %. - **Override** individual dimensions, and set a default for everything untagged. - The dimension list is searchable and paginated, so it stays responsive even for products with many dimensions. **GCP amendment (replacement) offers.** Tag-based discounts are no longer limited to new offers. A GCP **amendment** offer priced **postpay** shows the same tag-discount panel, and reopening one re-applies the tag rules that were saved with it rather than flattening them back to per-dimension rates. **Configuration rule library.** The discount panel has a **rule library** modal for reusing rules already saved in your org: select rules individually or with a select-all control, and a rule already applied to this offer carries an **Applied** badge so you do not add it twice. ### Percent vs. Absolute pricing (AWS & Azure) AWS and Azure offers can price a dimension either as a **percentage** off the product list rate or as an **absolute** negotiated price. A **Percent / Absolute** toggle switches between the two faces without losing the entered values: - **Percent** — the tag-filter discount panel; the final rate is `list × (1 − discount%)`. - **Absolute** — a flat fixed-price editor; you enter the negotiated price directly and the panel shows the equivalent discount for reference. When you reopen a hand-priced (legacy) offer whose rates differ from the current product list, it opens in **Absolute** so your negotiated prices are preserved exactly. ### Azure per-plan configuration Azure offers configure discounts **per plan**: each absolute-priced plan gets its own collapsible section, so plans that share a meter can be discounted independently, and a single offer can mix percentage plans with absolute plans. For GCP **prepay** offers with multiple installments, each editable installment is configured independently; already-charged (locked) installments are shown read-only and are never changed. Dimension tagging does **not** apply to AWS Machine Learning, AWS Professional Service, AWS Reseller, or Azure Application / Virtual Machine offers — those keep their standard pricing. Any user who can create an offer can also **save a rule as a reusable discount group** to the org library. Applying discounts to the current offer never requires saving a group. :::note Dimension tags and the discount-group library are created and managed in the Fours web console. The Salesforce app consumes them when building offers; the discount actually applied to the offer is always reflected in the offer's native per-dimension prices. ::: --- Source: https://doc.fours.com/salesforce-app/salesforce-app-cppo/ # Create Reseller Authorization Easily create a reseller authorization (Channel Partner Private Offer / CPPO) using the Fours App within your Salesforce Console. --- ## Overview A reseller authorization — also called a Channel Partner Private Offer (CPPO) — is how you give a reseller or channel partner permission to sell your product on a cloud marketplace on your behalf. Here's how it works in plain terms: - You (the ISV) create a reseller authorization that sets the price you're willing to give the reseller. - The reseller then creates their own private offer to the end customer, using your authorization as the basis — at whatever markup they choose. - The end customer buys from the reseller through the marketplace, and billing flows through accordingly. Think of it as a wholesale price you set for your channel partner, who then handles the last mile to the customer. On Azure you can instead grant a standing [resale authorization](#azure-multiparty-private-offer-or-resale-authorization), which carries no price. :::warning A reseller authorization is **not** sent to an end customer — it is sent to the reseller. The reseller is the one who creates the final offer to the buyer. Make sure the opportunity you are creating this from is associated with a reseller, not the end customer. ::: For more details on resale, see [Channel Partner Private Offers (CPPO)](/aws-marketplace/cppo/). ## Prerequisites - The Fours App must be installed, connected, and set up with the Fours widget on your opportunity pages. If you haven't done that yet, work through [Install the Fours App](/salesforce-app/salesforce-app-install/) first. - You need the **Suger User**, **Suger User - Marketplace**, or a cloud-specific marketplace permission set assigned to your Salesforce account. If you can't see the **New Offer** button on an opportunity, your permission set is likely missing — see [Permission Sets](/salesforce-app/salesforce-app-permission-sets/). - The product you want to authorize must already exist in Fours. If it doesn't, create it in the Fours Console first. See [Products](/console/products/). ## Create a Reseller Authorization 1. Navigate to the opportunity's detail page (the opportunity associated with your reseller) and click the **New Offer** dropdown button at the top of the Fours App. If you don't see the widget, it may not be added to your page layout yet — see [Page Components](/salesforce-app/salesforce-app-page-components/). > New Offer dropdown button on Salesforce opportunity page 2. Locate and click the **"Reseller Authorization"** button. > Reseller Authorization option in New Offer menu 3. Choose the product on which the Reseller Authorization will be based and complete the required fields in the form. Note that the required fields may vary depending on the cloud marketplace and type of product. The product list shows only the products available in your Fours account — if you are assigned a cloud-specific permission set (e.g., Suger Marketplace - AWS), you will only see products for that cloud. > Product selection for reseller authorization > Reseller authorization form fields > :::tip > If field mapping has been configured, the form will be prefilled with corresponding fields from the Salesforce opportunity, making the offer creation process faster and easier. Review the pre-filled values for accuracy before submitting. > ::: > :::tip > **Reseller not in the list? (AWS)** If the reseller's AWS account is missing from the reseller account dropdown, click **Add reseller manually** below the dropdown. Enter the reseller's 12-digit AWS account ID and an optional display name, then click **Add**. The entry is saved for your organization, is selected automatically, and appears in the list on future offers. The account ID is not verified against AWS, so double-check it before submitting. > ::: > :::tip > **Naming the opportunity.** The **Opportunity Name** field takes a **minimum of 3 and a maximum of 100 characters**. On the AWS reseller authorization form the only rejected characters are `;` `"` `'` `<` `>` and `\` — everything else is accepted, including **spaces**, forward slashes, periods, and parentheses. > > This is worth knowing if you follow AWS's own recommended naming convention, `ResellerName_ProductName_MM/YYYY`. The form previously enforced a strict alphanumeric/underscore/hyphen pattern, so the slash in the date was rejected and teams had to rewrite the name to get the authorization submitted. That is no longer the case — enter the convention exactly as AWS documents it, for example `Acme Corp_Analytics Platform_03/2026`. > ::: 4. Once all necessary information is filled in, submit the form to create the offer. > Completed reseller authorization form ready to submit 5. You are all set! ### AWS: choose the currency The AWS reseller authorization form has a **Currency** section — *Choose a transaction currency for this offer. You will receive payment in the selected currency.* — with **USD**, **AUD**, **CAD**, **GBP**, **EUR** and **JPY**, USD by default. A currency your AWS Marketplace integration doesn't support is refused when you submit: *the currency code … is invalid for AWS marketplace*. ### AWS: commit term length The AWS reseller authorization form accepts a **commit term length** of up to **144 months** for **SaaS** products — contract or subscription — and up to **60 months** for other AWS product types. ### Dates on a GCP reseller authorization Three dates on the GCP form are checked before the authorization is submitted. All three accept **today** — they are compared as calendar dates in your own timezone, so picking today is never rejected as being in the past: | Date | Rule | | --- | --- | | **Offer start time** | Today or later. *"The offer start time should be today or in the future."* | | **Acceptance Due Date** | Today or later, and within GCP's three-month acceptance window. A later date passes the form but is refused when you submit: the **Failed to create CPPO_OUT** message contains *the offer expiration date (…) is too late. Google Cloud Marketplace requires offers to expire within 3 months, so choose a date on or before …* — pick that date or an earlier one. | | **Scheduled start date** | Today or later, when the start policy is **On a scheduled date** and you are setting custom payment installments. | The offer end time must be **on or after** the start time, and the installment start date on the form is labelled **(UTC)** because the installment arithmetic runs in UTC. ### GCP: reseller discount **Reseller Discount (%)** on the GCP reseller authorization and its replacement form accepts any value from 0 to 100 with up to six decimal places. The replacement form also refuses to replace a reseller authorization that GCP already shows as ended — expired, cancelled, lapsed, or failed approval — unless its entitlement is pending cancellation. See [GCP replacement offers](/salesforce-app/salesforce-app-offer/#gcp-replacement-offers-term-and-cancellation) for the message and what to do instead. ### Azure: multiparty private offer or resale authorization The Azure reseller authorization form opens with a **Private Offer Type** choice: | Type | What it creates | | ---- | --------------- | | **Multiparty private offer** (the default) | You and an authorized partner sell a personalized offer with custom payouts to a Microsoft customer. The form works as described above. | | **Resale authorization** | A standing grant, not a private offer. A resale partner may sell this product on your behalf in the customer markets you choose, and creates their own private offers for it in Partner Center. It has no pricing, dates or terms of its own, and you can revoke it at any time. | **Resale authorization** is offered only for SaaS products (including the Flat Rate and Per User types) and Virtual Machine products — Microsoft supports resale-enabled offers for no other type. A draft that already holds a resale authorization keeps the option. Choosing **Resale authorization** cuts the form down to **Offer Name**, **Private Offer Type**, the two fields below, and **Internal Notes**. Everything else — the partner and buyer fields, description, dates, pricing, EULA, customer renewals and notification contacts — does not apply, so it is not shown. | Field | What to enter | | ----- | ------------- | | **Resale partner's seller ID** | The Partner Center seller ID of the partner you are authorizing. The partner finds it in Partner Center under **Account settings** → **Identifiers**, in their organizational profile. | | **Customer markets** | The markets where the partner may sell. Move markets from **Available** to **Authorized**, or use **Select all** / **Clear all**. At least one is required. | Brazil, Belarus, India, South Korea, Mexico, Russia and Singapore are never offered, because Microsoft does not support resale-enabled offers in those markets. A saved draft that still lists one of them drops it when you reopen it, so the authorization can be submitted. **Pre-fill a resale authorization from Salesforce.** Your admin can map both fields from Salesforce in the private offer field mapping for Azure — in the Fours Console, open **Offer**, then **Settings** → **CRM**, and edit the configuration in the **Salesforce** block. When the record supplies a **Resale partner's seller ID** or **Customer markets**, the form opens with **Resale authorization** selected and those fields filled in. **Customer markets** reads two-letter country codes from a multi-select picklist or a semicolon-separated text field, such as `us;gb`, and an unsupported market is still dropped. Both fields are unmapped by default, so the form otherwise opens on **Multiparty private offer**. For how mapping works, see [Private Offer Field Mapping](/settings/private-offer-mapping/). If a required field is missing, the form stops with *Please enter the resale partner's seller ID.* or *Please select at least one customer market.* For how resale authorizations work on the Azure side, see [Azure CPPO](/azure-marketplace/cppo/#create-a-resale-authorization). ### EULA files merge in the order shown On the AWS, Azure and GCP forms, the **EULA** section merges the PDFs you attach in the order shown, with the standard contract (if attached) appended last, and uses the same reorder arrows as a private offer — see [Attach your own EULA files](/salesforce-app/salesforce-app-offer/#attach-your-own-eula-files). The AWS **Reseller Agreement** list has no reorder arrows. ### What happens next? After you submit the reseller authorization: - Fours creates the reseller authorization record in your Salesforce org, linked to the opportunity. - The authorization is sent to the cloud marketplace for processing. - Once confirmed by the marketplace, the reseller receives access to the authorization and can create their own private offer to the end customer. - You can track the status of the authorization from the offer record in Salesforce or in the Fours Console. :::note **An AWS resale authorization cannot have its expiry date extended.** AWS rejects any change to a resale authorization once it has been released, so the **Extend** action is not offered on AWS `CPPO_OUT` offers at all. To change the window, cancel the authorization and issue a new one. ::: ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | No New Offer button visible on the opportunity | Fours permission set not assigned, or the Fours widget is not on the page | Check your permission set. If the widget is missing, add it. | | Reseller Authorization option is not in the New Offer dropdown | The product type or cloud does not support CPPO, or your permission set restricts access | Confirm your product supports reseller authorization for the target cloud. Check your permission set assignment. | | Product list is empty | No products have been set up in Fours, or your permission set restricts which clouds you can see | Confirm products exist in the Fours Console. Cloud-specific permission sets only show products for that cloud. | | Form fields are blank — not pre-filled from the opportunity | Field mapping has not been configured | Field mapping is an optional admin setup. Contact your Salesforce admin to configure it. | | The reseller is not in the reseller account dropdown (AWS) | The reseller has not yet been crawled from AWS Marketplace | Click **Add reseller manually** below the dropdown and enter the reseller's 12-digit AWS account ID. | | Reseller authorization was created but does not appear on the opportunity | Sync between Fours and Salesforce is delayed | Refresh the page after a few minutes. If it still doesn't appear, confirm the authorization was created in the Fours Console. | | **Opportunity Name** is rejected by the form | The name is under 3 characters, over 100 characters, or contains one of `;` `"` `'` `<` `>` `\` | Adjust the name to fit. Spaces, forward slashes, periods, and parentheses are allowed, so AWS's `ResellerName_ProductName_MM/YYYY` convention is valid as written. | ## Frequently Asked Questions (FAQs) **Q: What's the difference between a reseller authorization and a private offer?** A private offer goes directly to an end customer. A reseller authorization goes to a channel partner (reseller), who then creates their own private offer to the end customer. Use a reseller authorization when you're selling through a partner, not directly to the buyer. **Q: Does the reseller see my cost price when I create a reseller authorization?** Yes — the reseller sees the price you set in the authorization. They can then mark it up when creating their own offer to the end customer, but they cannot go below the price you've authorized. **Q: Which cloud marketplaces support reseller authorization (CPPO) from Salesforce?** Check which products appear in the product selector — if products for a specific cloud are missing, that cloud may not yet support CPPO from Salesforce. Contact Fours support to confirm. **Q: Can I track whether the reseller has acted on the authorization?** Yes. You can check the status of the reseller authorization from the offer record in Salesforce or in the Fours Console. **Q: Do I need a separate opportunity for each reseller I authorize?** That depends on your Salesforce setup and sales process. Fours links the reseller authorization to whichever opportunity you create it from. If you have multiple resellers, most teams create a separate opportunity per reseller to keep records clean. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-cosell/ # Create Co-Sell Submit a co-sell referral to AWS, Azure, or GCP directly from a Salesforce opportunity using the Fours App. --- ## Overview A co-sell referral is how you formally ask AWS, Azure, or GCP to work with you on a deal. When you submit a referral, the cloud provider's sales team can see the opportunity and engage to help you close it — for example, by introducing you to the right contacts, validating the opportunity, or contributing resources. In plain terms, you're sharing a deal with your cloud partner so they can help you win it. After adding the Fours App to your Salesforce Console, you can create co-sell referrals from opportunities with ease. :::info Submitting a co-sell referral does not send anything to your customer. It only shares the opportunity details with the cloud provider's partner team. Your customer will not know a referral was submitted. ::: ## Prerequisites - The Fours App must be installed, connected, and set up with the Fours widget on your opportunity pages. If you haven't done that yet, work through the Getting Started and Salesforce Admin Setup steps first. - You need the **Suger User**, **Suger User - Cosell**, or a cloud-specific co-sell permission set assigned to your Salesforce account. If you can't see the **Co-Sell** button on an opportunity, your permission set is likely missing or incorrect. :::note **GCP co-sell needs a co-sell integration, not a marketplace one.** The GCP co-sell surfaces appear only when your org has a **verified GCP integration whose service is Co-Sell**. A GCP *marketplace* integration on its own does not turn them on — the two are separate integrations. AWS co-sell requires an AWS ACE integration, and Azure co-sell requires an Azure marketplace integration with co-sell enabled on it. ::: ## Create a Co-Sell 1. Navigate to the opportunity's detail page and click the **Co-Sell** button at the top of the Fours App. If you don't see the widget, it may not be added to your page layout yet. > Co-Sell button on the Salesforce opportunity page 2. Choose the **cloud partner** you want to submit the referral to — AWS, Azure, or GCP — and fill the form with the necessary information. Required fields vary depending on which cloud partner you selected. > Cloud partner selector for a new co-sell referral > AWS co-sell referral form fields > :::tip > If field mapping has been configured, the form will be prefilled with corresponding fields from the Salesforce opportunity, making the co-sell creation process faster and easier. Review any pre-filled values for accuracy before submitting. > ::: 3. Once all necessary information is filled in, submit the form to create the co-sell. > Submit button on the AWS co-sell referral form 4. You are all set! ### What happens next After you submit the referral: - Fours creates a referral record in your Salesforce org, linked to the opportunity. - The referral is sent to the cloud partner's system — for example, AWS Partner Central (ACE), Azure Partner Center, or Google Cloud Partner Network. - The cloud partner reviews the referral and may accept, reject, or request more information. - Any future updates you make to the Salesforce opportunity are automatically synced to the referral — you do not need to manually push updates to the cloud partner. Fours scans your pipeline once per hour and updates the referral based on changes to the linked deal. - If the cloud partner scores or updates the referral on their side (for example, AWS assigning an engagement score), those updates appear on the referral record in Salesforce after the next sync. ## Create Salesforce Records from a Fours Referral For **Fours (PRM) deal-reg referrals**, you can create a linked Salesforce Opportunity or Account directly from the referral — no need to navigate away and create the record manually. **From the referral record (Actions sidebar):** On the referral's detail page, the **Opportunity** and **Account** cards do more than create records — they are how you attach the referral to the right Salesforce record and correct it later. Which actions the card offers depends on whether a record is linked yet: | Action | Shown when | What it does | | ------ | ---------- | ------------ | | **Create** | Nothing linked yet | Opens a pre-filled form with fields populated from the referral's customer and deal information (such as company name, contact, and deal amount). Review or adjust the values, then submit. The new Opportunity or Account is automatically linked to the referral. | | **Link** | Nothing linked yet | Attaches an Opportunity or Account that **already exists** in Salesforce, without creating anything new. | | **View** | A record is linked | Opens the linked Opportunity or Account record. | | **Edit** | A record is linked | Edits the linked record in place from the referral. | | **Unlink** | A record is linked | Detaches the record from the referral. The Salesforce record itself is not deleted — the card returns to its unlinked state, so you can then **Link** the correct one. | In day-to-day use **Link** and **Unlink** matter more than **Create**: the Opportunity or Account usually already exists in Salesforce, and the work is pointing the referral at the right one — or repointing it when a referral landed on the wrong record. **Create** is for the case where the deal genuinely has no Salesforce record yet. **View** is available to anyone who can see the referral. **Create**, **Link**, **Edit**, and **Unlink** require referral write access — with a read-only permission set (for example `Suger User Cosell Read`) you will only see **View**. **Linking an offer:** the referral's **Offer** card carries the same Link/View/Edit/Unlink actions, and its **Link** action opens a searchable offer picker — search by offer **name**, **ID**, or **external ID**. The search runs on the server against your organization's full offer list rather than filtering a preloaded page, so it still finds the right offer in an org with a large offer catalog. **After accepting an inbound Fours referral:** When you accept an inbound Fours referral, you are prompted to create linked Salesforce records as an optional next step. You can create an Opportunity, an Account, or both. Fields are pre-filled from the referral data where available. Skipping this step is fine — you can always use the **Create** button on the cards later. :::note Pre-fill is best-effort: values are derived from the referral's customer and deal info and may not cover every Salesforce field. Review the form before submitting. ::: Fours partner-to-partner (PRM) referrals are also included in the **periodic Salesforce backfill**, not only in single-record syncs — so a deal-reg referral that was created or changed between syncs still arrives in Salesforce on the next backfill run, without anyone pushing it across by hand. ## Contacts on an AWS referral AWS referrals carry contacts from three different sides of the deal, and the app keeps them separate so it is always clear who owns a given name. ### On the AWS referral detail page Contacts are grouped into three accordion sections, ordered by who owns the record — the customer, then AWS, then you: | Section | Who is in it | | ------- | ------------ | | **Customer Contacts** | The end customer's people — the contact details submitted with the referral. | | **Cloud Contacts (AWS)** | AWS-side people on the deal, such as the partner development manager. | | **ISV Contacts** | Your own people on the deal — the partner contacts you supplied when sharing the referral. | Each section shows its own empty state ("No contacts found") when there is nobody in that group yet, so an empty **Cloud Contacts (AWS)** section usually just means AWS has not assigned anyone to the opportunity. **ISV Contacts** rows carry an **Edit** button for changing the person filling a role. AWS owns the role, so editing **preserves it**: the role renders as static text and only **first name**, **last name** (each up to 80 characters), **email**, and **phone** can be changed. A role can never be renamed or removed — you replace the person in it, or fill it when it is still empty. Phone is optional, but when given it must be in international format with a `+` and the country code, for example `+12025550170`. A number without the `+` is refused with *"Enter the phone in international format with a + prefix."* rather than having a country code guessed for it — the same rule as in the Fours Console. The two ISV roles render with their plain-English names rather than AWS's internal codes: | AWS role | Shown as | | --- | --- | | `PartnerAccountManager` | **Partner Account Manager** | | `OpportunityOwner` | **Partner Opportunity Owner** | AWS-side roles in **Cloud Contacts (AWS)** are deliberately *not* relabelled — AWS keeps adding to that list (PDM, WWPSPDM, ISVSM and others), and a fixed map would silently drop any role it did not know about. ### On the AWS co-sell form The AWS create form mirrors AWS Partner Central's *Add contact details* step: one **customer contact**, plus **two partner contacts whose roles are fixed for you**. | Section on the form | Role | | ------------------- | ---- | | **Customer contact** | The customer's contact. Its **Customer Title** is free text — you type whatever the person's title is. | | **Partner Contact - Owner** | Fixed role: **Opportunity Owner**. | | **Additional Partner Contact - Account Manager** | Fixed role: **Partner Account Manager**. | For the two partner contacts, the role is part of the section heading rather than a field you pick, so there is nothing to select — fill in the name, email, and phone and the role goes across correctly. Leaving a partner contact blank is fine: empty partner contacts are dropped when the referral is submitted. ## Your team on a Fours (PRM) referral The **Share with Fours** wizard and the **Accept** dialog both collect the people on your side of a partner-to-partner deal in a **Your Team** table rather than as a row of inputs: - **Add Contact** opens a picker where you choose a **Salesforce User**, a **Salesforce Contact**, or an existing **Suger contact** — or enter someone manually. At least one contact is required. - The table shows **Name**, **Email**, and **Title**. Only **Title** is editable inline; name and email come from the record the row is backed by, so a hand-edit cannot drift from it. Pick a different person instead of editing a name. - Each row's action menu offers **Delete**. There is **no role picklist** on these rows — the roles are implied by the deal's two sides, so there is nothing to select. ## APN Programs on an AWS referral **APN Programs** is a multi-select on the AWS referral. The package carries the full AWS list of **eighteen** programs, including **Cloud Adoption Framework Program (CAF)**, **P3**, **WWPS NDPP**, and **Model Provider PARC**: | | | | | --- | --- | --- | | APN Immersion Days | ISV Immersion Day SFID Program | Partner Opportunity Acceleration Funded | | APN Solution Space | ISV Workload Migration | The Next Smart | | ATO (Authority to Operate) | Migration Acceleration Program | VMware Cloud on AWS | | AWS Marketplace Campaign | Model Provider PARC | Well-Architected | | Cloud Adoption Framework Program (CAF) | P3 | Windows | | Partner Launch Initiative | Workspaces/AppStream Accelerator Program | WWPS NDPP | **Seventeen of the eighteen are selectable when you share a referral outbound** — every one above except **Model Provider PARC**. All eighteen are selectable when you edit a referral **that AWS originated**. :::warning **Model Provider PARC cannot be selected on an outbound referral.** AWS rejects it on a partner-originated opportunity (*"APN Programs: Model Provider PARC is not valid for partner-originated opportunities"*), and that rejection blocks every later change to the referral — so it is left out of the outbound selectors. It stays selectable in the referral list **filter**, and in **Edit AWS Opportunity** on a referral that AWS originated: those opportunities do carry it, and you can clear it and tag it again there. The test is the opportunity's **Origin** (`AWS Referral`), not the referral's inbound/outbound direction. ::: The referral detail page shows the selected programs under **APN Programs** in *Project Detail*, semicolon-separated (`Model Provider PARC; Well-Architected`). The **Apex Action** accepts that value as-is — it trims each program, so a string copied from the detail page works whether or not you remove the spaces. ## Timestamps on the referral detail page Every referral pane shows how fresh the partner's copy is, read from Fours' unified external timestamps rather than from each partner's own payload: | Pane | Date rows | | --- | --- | | **AWS** | Created Date, **Last Updated Date** | | **GCP** | Creation Date, **Last Updated Date** | | **Azure** | **Created Date** and **Last Updated Date** | Both render as `YYYY-MM-DD HH:MM` — for example `2026-09-02 16:12` — on a 24-hour clock, in **your own timezone**. That is the same `YYYY-MM-DD` the other dates on the pane use (Estimated Close Date, Target Close Date, Submitted Date), so a whole pane reads in one format; the time of day is kept because a "last updated" without an hour cannot tell you whether the partner's copy moved this morning or last week. An Azure draft that Partner Center has never seen renders both blank. The **Opportunity** card on the referral also shows the CRM-side **Stage**, so the partner's stage and your Salesforce stage can be compared without opening the Opportunity record. ## Notes & Attachments on a Referral Every referral detail view (AWS, Azure, GCP, and Fours deal-reg) has a **Notes & Attachments** section at the bottom of the page, so the deal's supporting materials — private offer PDFs, deal-registration confirmations, customer requirement documents, call notes — live on the referral itself instead of scattered across email and drives. **What you can do:** - **Upload Files** — attach one or more files to the referral. Files are stored as standard Salesforce Files, so they also appear in Files home, global search, and reports. - **New Note** — write a titled note with basic formatting (bold, italic, underline, lists). Notes are standard Salesforce enhanced notes: you can open and edit them later with the native note editor, and they render identically there. - **Preview / Download / Delete** — each row's action menu opens the native file preview, downloads the original file, or removes the item from the referral. A file that is only attached to this referral is permanently deleted; a file that is also attached to other records is detached from this referral only (the file itself is kept, along with its other locations). **Delete is only offered on items you added yourself** (Salesforce file ownership rules); other people's items are managed by their owners or by an admin through standard Files pages. **Permissions:** the section follows your referral permissions. With read-only access (for example the `Suger User Cosell Read` permission set) you can view, preview, and download items, but the upload, note, and delete controls are hidden. :::note - Notes require **Enhanced Notes** to be enabled in your org (Setup → Notes Settings). When it is off, note creation is hidden and file attachments continue to work. - Items are attached to the referral's Salesforce record. If a referral is withdrawn and re-registered under a **new** referral ID, items attached to the previous ID do not carry over to the new referral. ::: ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | No Co-Sell button visible on the opportunity | Fours permission set not assigned, or the Fours widget is not on the page | Check your permission set. If the widget is missing, add it to your page layout. | | Only one or two cloud partners appear in the partner selector | Your permission set restricts co-sell access to specific clouds | If you need access to additional clouds, ask your Salesforce admin to update your permission set. | | Form fields are blank — not pre-filled from the opportunity | Field mapping has not been configured | Field mapping is an optional admin setup. Contact your Salesforce admin to configure it. | | Referral was submitted but does not appear on the opportunity | Sync between Fours and Salesforce is delayed | Referral records sync on a schedule. Refresh the page after a few minutes. If it still doesn't appear, confirm the referral was created in the Fours Console. | | An AWS referral's **Engagement Score** reads **Not provided by AWS** | AWS has not scored this opportunity yet | The referral shows AWS's own score once AWS scores the opportunity. The field API name is `Suger__AWS_EngagementScore__c` if you want to use it in automations. The **Suger Predicted Engagement Score** in the Fours widget is Fours' own prediction, not AWS's: it is never written to the referral, so it does not fill this field. Azure and GCP supply no score of their own, so their referral cards show a **Suger Predicted Engagement Score** row instead. | | A referral created directly in AWS ACE is not showing in Salesforce | ACE referrals only sync to Salesforce after an update event | The referral appears in Salesforce after AWS accepts it or after you manually edit something. To link it to a specific opportunity, enter the Salesforce opportunity ID in the **Partner CRM Unique Identifier** field in ACE. | | A referral has a **Partner CRM Unique Identifier** in ACE but is not linked to the opportunity | Something other than a Salesforce Opportunity ID is in the field | Either spelling of the Salesforce Opportunity ID works — the **15-character** case-sensitive form and the **18-character** form are both normalized before matching, so you can paste whichever one your org surfaces. If the link still doesn't form, check that the value really is an Opportunity ID and that the opportunity exists in the connected org. | | After **Accept** or **Reject** on an AWS engagement invitation, the referral does not change | AWS refused the request | Hover the icon on the invitation's status badge: it reads **Update Failed:** followed by AWS's reason. The referral keeps its previous status, and the message clears when a later accept or reject succeeds. | | Changes to the Salesforce opportunity stop reaching its AWS referral, which shows **Update Failed** with a reason starting **CRM sync rejected:** | Fours' AWS update check rejected the values the sync derived from the opportunity — for example, *Once the opportunity reaches Committed stage or beyond, 'Other' is no longer accepted — please select a valid solution identifier.* The referral keeps its status, and nothing is sent to AWS. | To read the full reason, hover the error icon beside the referral's status on its card in the Fours widget, or, on a partner-originated referral, open its **Status** panel. Correct what the reason names: the value mapped from the opportunity, or the referral data it conflicts with (in the example, a valid solution). The sync re-checks the opportunity on every scheduled run, and once the values pass, a later sync clears the message. | ## Frequently Asked Questions **Q: What's the difference between a co-sell referral and a private offer?** A co-sell referral shares your deal with the cloud provider's partner team so they can help you close it. A private offer is a custom-priced contract you send directly to a buyer. They serve different purposes — co-sell is about getting the cloud partner involved in the deal; a private offer is the actual transaction. **Q: Do I need to manually update the referral every time the opportunity changes?** No. Fours automatically syncs changes from your Salesforce opportunity to the referral once per hour. If you update the close date, stage, or any mapped fields on the opportunity, those changes flow through to the cloud partner automatically. **Q: Can I submit a referral to more than one cloud partner for the same opportunity?** Yes. You can submit separate co-sell referrals to AWS, Azure, and GCP from the same opportunity — just click **Co-Sell** again and select a different partner. **Q: Can I see the AWS engagement score on the opportunity page rather than just on the referral record?** Not by default, but it is possible. Your Salesforce admin can set up a formula field on the Opportunity object that pulls in the score from the referral record. The field API name is `Suger__AWS_EngagementScore__c`. That field holds only AWS's own score for the opportunity. The **Suger Predicted Engagement Score** shown in the Fours widget is not stored on the referral, so a formula cannot pull it in. **Q: What happens if I created a referral directly in AWS ACE instead of through Salesforce? Will it show up?** Yes, but not immediately. It appears in Salesforce after AWS accepts it or you manually edit something in ACE. To connect it to the right Salesforce opportunity, enter the opportunity's Salesforce ID in the **Partner CRM Unique Identifier** field in ACE — Fours will then associate them automatically. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-install/ # Install the Fours App Install the Fours managed package from Salesforce AppExchange and establish a live, two-way connection between Salesforce and Fours. --- ## Overview By the end of this guide, you will have: - The Fours package installed in your Salesforce org - A dedicated Integration User set up for the connection - A live, verified two-way connection between Salesforce and Fours You only need to complete this setup once. :::warning **Do not use a personal Salesforce user account for the integration.** You will create a dedicated Integration User in Step 2. Using a personal account means the connection breaks if that person leaves or changes roles. ::: --- ## Prerequisites Make sure you have the following before you begin: - **Salesforce Administrator access** — required to install packages and create users. - **A Fours account** — sign in at [console.suger.io](https://console.suger.io/). - **Your Fours Organization ID** — found in [Settings → Organization & Users](https://console.suger.io/settings?tab=organization). - **A Fours API Key** — generated in [Settings → API Client](https://console.suger.io/settings?tab=api_client). --- ## Step 1: Install the Fours package from AppExchange This installs the Fours App into your Salesforce org. 1. Go to the [Suger listing on Salesforce AppExchange](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3u00000RMskLEAT). 2. Click **Get it Now**. 3. Log in with your Salesforce Admin account when prompted. 4. Choose where to install: - Select **Production** for your live org. - Select **Sandbox** if you are testing first. 5. When asked who to install for, select one of the following: - **Admins Only** — recommended to start; you can expand access later. - **All Users** — installs for everyone immediately. - **Specific Profiles** — installs only for selected profiles. 6. Click **Install** and wait for the confirmation email from Salesforce. :::note The confirmation email may take a few minutes to arrive. Do not click **Install** again — Salesforce is processing the request in the background. ::: --- ## Step 2: Create a dedicated Integration User The Integration User is a special Salesforce account that Fours uses to read and write data in your org. It is not a person — it is a service account. ### Choose a license type Pick the right license before creating the user. | License type | When to use | | --- | --- | | Salesforce Integration License | Use this in most cases. It is free and designed for API-only connections. The user cannot log in via the Salesforce UI. | | Salesforce License (standard) | Use this only if your field mapping involves Quote objects — either a standard Salesforce Quote or a CPQ Quote. | :::note If you are using Salesforce CPQ (also called SBQQ), you also need to assign a CPQ license to this user on top of the standard Salesforce License. ::: ### Create the user 1. In Salesforce, click the **Gear icon (⚙️)** → **Setup**. 2. In the **Quick Find** box, type `Users` and select **Users**. 3. Click **New User**. 4. Fill in the required fields: - Enter a recognizable name like `Fours Integration`. - Enter a valid email address — Salesforce will send an activation link here. - Set the **License** to whichever option you chose above. 5. If you selected **Salesforce Integration License**, set the **Profile** to **Salesforce API Only System Integrations**. 6. Click **Save**, then activate the user via the email Salesforce sends. ### Assign permission sets to the Integration User Permission sets control what data Fours can access in your org. You need to assign two things. #### First — assign the Suger Integrator permission set 1. Go to **Setup** → **Permission Sets**. 2. Find and open the permission set that matches your license type: - **Salesforce Integration License** → assign **Suger Integrator (Salesforce Integration License)**. - **Salesforce License** → assign **Suger Integrator**. 3. Click **Manage Assignments** → **Add Assignments** → select your Integration User → **Assign**. #### Second — create a custom permission set for object access Fours also needs read access to standard Salesforce objects like Account, Contact, and Opportunity. Create a permission set for this manually. 1. Go to **Setup** → **Permission Sets** → **New**. 2. Name it something like `Fours Integration Object Access`. 3. Set the license to match your Integration User: - **Salesforce Integration License** → select **Salesforce API Integration** _(not "Salesforce Integration" — these are different)_. - **Salesforce License** → leave the license field as default. 4. Inside the permission set, grant **Read** and **View All** access on: - Account - Contact - Opportunity - Any other objects or fields you plan to use in your Fours field mapping. 5. If you are using standard Salesforce Quotes, also grant **Read** access on Product2, Pricebook2, and Quote. 6. Save the permission set, then assign it to your Integration User using the same steps above. :::note For a full reference of the Fours permission sets available in the package, see [Permission Sets](/salesforce-app/salesforce-app-permission-sets/). ::: --- ## Step 3: Configure Salesforce to talk to Fours This step tells Salesforce where Fours is and how to authenticate with it. You do this from inside the Fours App in Salesforce. 1. In Salesforce, click the **App Launcher** (the nine-dot grid icon in the top-left) and search for **Suger**. 2. Open the Suger app and navigate to **Settings**. 3. Fill in the following fields: | Field | What to enter | | --- | --- | | Organization ID | Your Fours Org ID from [Settings → Organization & Users](https://console.suger.io/settings?tab=organization). | | API Endpoint | `https://api.suger.cloud` | | API Key | Your Fours API Key from [Settings → API Client](https://console.suger.io/settings?tab=api_client). | 4. Click **Save**. :::warning **Double-check your API Key for trailing spaces.** A space at the end is invisible but will cause authentication to fail. ::: --- ## Step 4: Connect Fours to Salesforce This step goes in the other direction — it authorizes Fours to read and write data in your Salesforce org using the Integration User you created in Step 2. 1. Go to [Fours Console](https://console.suger.io) → **Settings** → **Integrations** → **Salesforce**. 2. Click **Connect Now**. 3. Enter your **Salesforce Subdomain** — for example, `acme.my.salesforce.com`. - Find this in Salesforce at **Setup** → **Company Settings** → **My Domain**. 4. If you are connecting to a Sandbox org, check the **Sandbox** checkbox. 5. Click **Create**. 6. Salesforce will prompt you to log in — sign in as the **Integration User** you created in Step 2, not your personal admin account. 7. After logging in, return to Fours Console and click **Verify** to confirm the connection is live. :::note If you need to reconnect later — for example, after changing OAuth policy settings in Salesforce — return to this screen and click **Connect Now** again. ::: For more detail on the integration configuration and mapping options, see the [Salesforce Integration Setup Guide](/integrations/salesforce/). Which Fours objects are written into Salesforce, and how far back each one goes, is set on the integration's **Backfill To Salesforce Configuration** tab — see [Choose What Backfills to Salesforce](/integrations/salesforce/#choose-what-backfills-to-salesforce). --- ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | API Key authentication fails | Trailing space in the API Key field | Delete and re-enter the API Key, making sure there are no spaces before or after it. | | "Not approved for access" error during OAuth | Integration User's profile is not listed under Permitted Users in the Suger External Client App | Go to **Setup** → **External Client App Manager** → **Suger** → **Policies** and add the Integration User's profile or permission set under Selected Profiles/Permission Sets. | | Fours buttons not visible after connection | User has not been assigned the correct Fours permission set | Go to **Setup** → **Permission Sets** and assign the appropriate [Fours permission set](/salesforce-app/salesforce-app-permission-sets/) to the user. | | Users can see buttons they should not | Extra custom permissions were auto-enabled when the package was installed | Go to the user's profile → **Custom Permissions** and uncheck any Fours permissions that should not apply. | | Connection works but data is not syncing | Integration User lacks Read/View All access on required objects | Review the custom object permission set you created in Step 2 and add any missing object or field access. | | Salesforce Integration License user cannot log in | This is expected — the Salesforce Integration License is API-only by design | Use a standard Salesforce License if your team needs the Integration User to log in via the UI. | --- ## Frequently Asked Questions **Do I need to reinstall the package every time Fours releases an update?** No. Fours pushes managed package updates automatically. You do not need to reinstall from AppExchange to get new features. **Can I use my personal Salesforce Admin account as the Integration User?** You can, but it is not recommended. If your account is deactivated, renamed, or its password changes, the Fours connection breaks. A dedicated Integration User keeps the connection stable regardless of staff changes. **Can I connect Fours to both a Production org and a Sandbox at the same time?** Yes. In Fours Console → **Settings**, you can add additional environments. Check the **Sandbox** checkbox when connecting a sandbox org. **What is the difference between the Suger Integrator permission set and the custom object permission set I created in Step 2?** The **Suger Integrator** permission set gives the Integration User access to Fours' custom objects and features. The custom object permission set you created gives Fours access to your standard Salesforce objects like Account and Opportunity. Both are required. **What happens if I click "Connect Now" again on an existing connection?** It re-initiates the OAuth flow. Use this if the connection breaks, or if you have updated OAuth policy settings in Salesforce and need to reauthorize. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-assign-permission-sets/ # Assign Fours Permission Sets to Your Team Assign the correct Fours permission set to each person on your team so they see the right Fours tabs and action buttons in Salesforce. --- ## Overview Fours permission sets work like job roles for the Fours App. Each set controls two things: - **Which Fours tabs are visible** — for example, the Offers tab or the Referrals tab. - **Which action buttons appear** — for example, the **New Offer** or **New Co-Sell** button on an opportunity record. Every person who uses the Fours App needs at least one permission set assigned to them. Without one, they won't see any Fours buttons or tabs. :::note Users with Salesforce System Administrator access automatically have full access to all Fours features. You do not need to assign a permission set to them. ::: For full permissions details, see [Custom Permissions](/salesforce-app/salesforce-app-custom-permissions/). --- ## Prerequisites - The Fours App must already be installed in your Salesforce org. See [Salesforce Integration](/integrations/salesforce/). - You need **Salesforce Administrator access** to assign permission sets. --- ## Step 1: Find the Right Permission Set for Each Person Use the tables below to pick the right permission set based on what each person needs to do. ### For Most Users — Start Here | Permission set | What they can do | Assign to | | --- | --- | --- | | Suger User | Full read/write access to all Fours features across all clouds — offers, referrals, entitlements, buyers, and products. Cannot access Fours Settings. | Power users, sales ops, or anyone who works across multiple clouds | | Suger User - Read Only | View all Fours data across all clouds. Cannot create or edit anything. | Managers, executives, or anyone who only needs visibility | | Suger User - Marketplace | Create and manage offers and entitlements across all clouds. No access to co-sell referrals. | Sales reps focused on marketplace deals | | Suger User - Cosell | Create and manage co-sell referrals across all clouds. No access to offers or entitlements. | Business development or partner managers focused on co-selling | | Suger Approval Offer | Approve or reject marketplace offers. | Deal desk, sales managers, or anyone in an offer approval workflow | | Suger Approval Cosell | Approve or reject co-sell referrals. Assign separately if someone should approve referrals but not offers, or the other way round. | Partner managers or anyone in a co-sell approval workflow | ### For Cloud-Specific Access Use these if a team member should only work with one cloud provider — for example, an AWS-focused rep who should not see Azure or GCP records. :::note Cloud-specific marketplace permission sets (for example, Suger Marketplace - AWS) automatically include access to shared objects like Buyers, Companies, and Products. The cloud restriction only applies to Offers and Entitlements. ::: **Marketplace (offers and entitlements)** | Permission set | Cloud access | | --- | --- | | Suger Marketplace - AWS | AWS offers and entitlements only | | Suger Marketplace - Azure | Azure offers and entitlements only | | Suger Marketplace - GCP | GCP offers and entitlements only | | Suger Marketplace (Read Only) | View-only access to offers and entitlements across all clouds | Snowflake and Oracle have their own marketplace sets as well — see the full catalog in [Permission Sets](/salesforce-app/salesforce-app-permission-sets/). **Co-sell (referrals)** | Permission set | Cloud access | | --- | --- | | Suger Cosell - AWS | AWS co-sell referrals only | | Suger Cosell - Azure | Azure co-sell referrals only | | Suger Cosell - GCP | GCP co-sell referrals only | | Suger Cosell (Read Only) | View-only access to referrals across all clouds | ### For the Integration User Only | Permission set | When to use | | --- | --- | | Suger Integrator | Assign to the Integration User created during installation. Do not assign this to human users — it grants full system access including Settings. | | Suger Integrator (Salesforce Integration License) | Same as above, but for Integration Users on a Salesforce Integration License. | --- ## Step 2: Assign the Permission Set Repeat these steps for each person who needs access to the Fours App. 1. In Salesforce, click the **Gear icon (⚙️)** → **Setup**. 1. In the **Quick Find** box, type `Permission Sets` and select **Permission Sets**. 1. All Fours permission sets start with the word **Suger** — scroll or search to find the one you want to assign. 1. Click the permission set name to open it. 1. Click **Manage Assignments**. 1. Click **Add Assignments**. 1. Find and select the user you want to assign it to. 1. Click **Assign**. --- ## Step 3: Verify the Assignment Worked Ask the user to log in to Salesforce and open a Salesforce opportunity record. They should see the Fours widget on the page with the buttons that match their permission set. For example: - A user with **Suger User - Marketplace** should see a **New Offer** button but no **New Co-Sell** button. - A user with **Suger User - Cosell** should see a **New Co-Sell** button but no **New Offer** button. - A user with **Suger User** should see both. If the right buttons are not showing, see the troubleshooting section below. --- ## Troubleshooting | Issue | Possible cause | Resolution | | --- | --- | --- | | User sees no Fours buttons or tabs at all | No Fours permission set has been assigned | Go back to Step 2 and assign the appropriate permission set | | User sees buttons they should not have access to | Extra custom permissions were auto-enabled when the package was installed | Go to the user's profile in Salesforce → Custom Permissions and uncheck any Fours permissions that should not apply | | User still sees wrong buttons after assigning the correct permission set | Salesforce cached the previous permissions | Ask the user to do a hard refresh — Cmd+R on Mac or Ctrl+Shift+R on Windows | | User cannot see records they should have access to | Object or field-level security (FLS) is blocking access | Verify the user has Read and View All access on Account, Contact, Opportunity, and any other objects relevant to their role | --- ## Frequently Asked Questions **Can I assign more than one Fours permission set to the same user?** Yes. For example, you can assign both **Suger Marketplace - AWS** and **Suger Cosell - AWS** to give a user full AWS access for both offers and referrals without giving them access to Azure or GCP. **What happens if I assign Suger Integrator to a regular user by mistake?** They will gain access to Fours Settings and all system-level features. Remove the permission set immediately and replace it with the appropriate user-facing permission set. **A user is a Salesforce System Administrator — do they need a Fours permission set?** No. System Administrators automatically have full access to all Fours features regardless of which permission sets are assigned. **I assigned the right permission set but the user still can't create offers for a specific cloud. What's wrong?** Check whether they have a cloud-specific permission set instead of a generic one. For example, **Suger Marketplace - AWS** only shows AWS products when creating an offer. If they need to create offers across multiple clouds, assign **Suger User - Marketplace** or **Suger User** instead. **What is the difference between Suger User - Marketplace and Suger User - Cosell?** Marketplace covers offers, entitlements, buyers, companies, and products. Co-sell covers referrals. They are separate because some teams — like a dedicated co-sell team — only need one and not the other. If a user needs both, assign **Suger User**. --- Source: https://doc.fours.com/salesforce-app/salesforce-app-leads/ # Work AWS Co-Sell Leads Work the earlier-stage prospects AWS sends you — accept the invitation, move the lead through the qualification funnel, and convert a qualified lead into a co-sell opportunity — and send your own Accounts to AWS for lead enrichment, without leaving Salesforce. --- ## Overview A **lead** is an earlier-stage prospect than an ACE opportunity. AWS Partner Central invites you to a lead it has sourced; you accept or reject that invitation, work the prospect through a qualification funnel, and — once it is genuinely qualified — convert it into a co-sell opportunity that follows the normal [referral lifecycle](/cosell/cosell-status/). Leads are **AWS-only**, and they reach you two ways: | Direction | How the lead starts | | --------- | ------------------- | | **Inbound** | AWS invites you to a lead it sourced, and you accept or reject the invitation. | | **Outbound** | You send one of your Salesforce Accounts to AWS for [lead enrichment](#enrich-an-account-into-an-aws-lead). AWS answers with what it knows about the customer, and Fours creates the lead from the answer. | From then on both kinds are qualified and converted the same way. The Salesforce app reads leads **live from Fours** rather than from the backfilled `Suger__Lead__c` records, so what you see in the tab matches the [Fours Console](/cosell/cosell-leads/) even between backfill runs. Accept, reject, qualify, convert, and enrich go straight through to AWS; linking a lead to an Opportunity or Account is saved in Fours. ## Prerequisites - The Fours App must be installed and connected, and your org must have an AWS co-sell (ACE) integration. See [Install the Fours App](/salesforce-app/salesforce-app-install/). - You need a permission set that grants **AWS referral** access — see [Who can see and work leads](#who-can-see-and-work-leads) below. Without one, the Leads tab is either missing or empty. ## Where to find leads Open the **Suger** app in Salesforce and click the **Leads V2 (Suger)** tab. If it is not in the navigation bar, add it the same way you add the Referrals tab — see [App Settings](/salesforce-app/salesforce-app-settings/). The tab renders a single **Co-Sell Leads** card listing every AWS lead in your organization. Its title carries the count — **Co-Sell Leads (38)**, or **Co-Sell Leads (12 of 38)** while a filter is narrowing the list. ### List columns | Column | What it shows | | --- | --- | | **Name** | The lead's name, as AWS supplies it. Click it to open the lead. | | **Direction** | **Inbound** for a lead AWS invited you to, **Outbound** for one Fours created by [enriching one of your Accounts](#enrich-an-account-into-an-aws-lead). | | **Company** | The prospect's company name. | | **Invitation Status** | Where the AWS invitation stands: `PENDING`, `ACCEPTED`, `REJECTED`, or `EXPIRED`. | | **Qualification** | How far you have worked the prospect — see [Qualify the lead](#qualify-the-lead). | | **Status** | The single unified status that folds the invitation, the qualification, and conversion together. | | **Readiness** | The AWS lead readiness score. | The card header has three controls: | Control | What it does | | ------- | ------------ | | **Filter** | Narrows the list to **All**, **Not Accepted**, or **Accepted**. | | **Inbound Sync** | Pulls this organization's latest leads from AWS now, instead of waiting for Fours' scheduled pull every three hours. A toast titled **Inbound sync started** says *AWS is being read now. Refresh in a few minutes to see new leads.* It needs AWS referral write access. | | Refresh icon | Re-reads the list from Fours. | The list shows **20** leads at a time; once there are more, a pager under the table reads, for example, *1–20 of 38*, with **Previous** and **Next**. There is no search box and the columns are not sortable — use the filter, or the [Fours Console](/cosell/cosell-leads/) list, when you need to narrow further. When your org has no leads yet the card reads *No co-sell leads found.* :::note The tab fetches every lead in your organization, 200 at a time, before it renders — on an org with a large lead history the card can sit on its spinner for a moment. The **Filter** and the pager then work on what is already loaded. ::: ## The lead lifecycle ```d2 direction: down pending: "Invitation Status = PENDING\nlead invitation from AWS" decide: "Accept or Reject?" { shape: diamond } rejected: "REJECTED\noptional reason sent to AWS" expired: "EXPIRED\ninvitation lapsed" enriched: "Outbound lead\ncreated by enriching an Account" accepted: "Invitation Status = ACCEPTED\nQualification picker appears" group: "Qualification funnel" { qualify: "Set Qualification\nOpen · Research · Qualified\nDisqualified · Unqualified" save: "Save\nwrites the value to AWS" gate: "Saved Qualification = Qualified\nand not already converted?" { shape: diamond } qualify -> save save -> gate } blocked: "Convert to Opportunity\nstays disabled" converted: "Converted Referral card appears\nco-sell opportunity created" pending -> decide enriched -> accepted: "no invitation —\nstarts accepted" decide -> accepted: "Accept" decide -> rejected: "Reject" pending -> expired: "no action before expiration" accepted -> group.qualify group.gate -> blocked: "no" blocked -> group.qualify: "keep working the prospect" group.gate -> converted: "yes — Convert to Opportunity" ``` ## Open a lead Click a row's **Name** to open **Lead Detail (Suger)**. The detail page has two halves: the lead record on the left, and the action cards on the right. ### The lead record The record opens with a row of badges — the invitation status, the lead status, the qualification, and the AWS lead ID — so you can tell what the lead is before opening a section. The sections below it are read-only and each can be collapsed: | Section | What it holds | | --- | --- | | **Basic Information** | Name, Status, Invitation Status, Partner. | | **Source record** | Only on an outbound lead: the **Salesforce object** it was created from — `Account` for an [enriched lead](#enrich-an-account-into-an-aws-lead) — and a link to that **Record ID**. | | **Customer** | Company Name, Website, Industry, Market Segment, AWS Maturity, Country, City, State/Province. | | **AI Readiness Insights** | Readiness Score, Qualification Status, Expiration, Marketplace Engagement Score, Solution Score, Solution Category, Solution Sub-Category. | | **Interactions** | One block per interaction: Use Case, Business Problem, Customer Action, Date, Source, Source Type, and the contact's name, title, email, and phone. Reads *No interactions recorded.* when AWS has sent none. | A value AWS did not send renders as an em dash. :::note A **pending** lead carries only the invitation summary, which AWS masks — so the Interactions section shows a single reduced block (Use Case, Source, Source Type, Contact Title) and the customer contact details stay empty. Accepting the lead is what makes AWS release the full context. ::: ### The Actions panel The right-hand side is a column of separate cards. The **Actions** card opens with status badges for the lead's invitation status, status, and qualification, and each card shows whichever controls apply: | Card | Controls | | --- | --- | | **Actions** | **Accept** and **Reject** while the invitation is `PENDING`; the **Qualification** picker, **Save**, and **Convert to Opportunity** once it is `ACCEPTED`. While **Convert to Opportunity** is disabled, the reason is written under it. | | **Opportunity** | **Link** when nothing is linked, **Edit** once something is. The linked ID is a link to the record. | | **Account** | **Link** / **Edit**, the same way — except on an outbound lead, where the card is read-only: its Account is the one the lead was enriched from, and it cannot be moved. | | **Converted Referral** | Appears only after conversion, with a **View** button onto the resulting referral. | **Waiting for AWS.** Accept, Reject, Save, and Convert each hand the change to AWS, which takes a few seconds to confirm it. Until it does, a notice at the top of the cards says what it is waiting for — for example *Waiting for AWS to confirm this lead as Qualified. The page updates itself when it does — this usually takes a few seconds.* — and the page re-reads the lead every few seconds until the change shows, so there is no need to reload. ## Accept or reject an invitation While the invitation is `PENDING`: - **Accept** takes the lead. The invitation status becomes `ACCEPTED` and the Qualification picker replaces the two buttons. - **Reject** declines it. Salesforce prompts *"Reason for rejecting this lead (optional):"* — the reason is optional, and is passed on to AWS when you supply one. Cancelling the prompt cancels the rejection. If you act on neither, the invitation lapses at its **Expiration** date and the lead becomes `EXPIRED`. ## Qualify the lead Once a lead is `ACCEPTED`, the **Qualification** picker in the Actions panel offers exactly five values: | Qualification | Meaning | | --- | --- | | **Open** | You have picked the prospect up. | | **Research** | You are actively investigating fit. | | **Qualified** | The prospect is a real opportunity. **This is the only value that unlocks conversion.** | | **Disqualified** | Not a fit — the lead stops here. | | **Unqualified** | The AWS default the moment you accept. Nothing has been worked yet. | A lead created by [enriching an Account](#enrich-an-account-into-an-aws-lead) starts at **Open** instead. Choosing a value does not save it. Click **Save** to write the change to AWS; the toast reads *Qualification sent to AWS. It appears here once AWS confirms.*, and Fours stores the value only after AWS accepts the write. ## Convert to an opportunity **Convert to Opportunity** turns the lead into a co-sell opportunity that then follows the normal referral lifecycle. The button renders only on an `ACCEPTED` lead, and stays **disabled** unless all three of these hold: - The qualification saved on the lead is exactly **Qualified**. - You have no unsaved change sitting in the picker — click **Save** first. - The lead has not already been converted. When one of them fails, the card says which, under the button: | Reason shown | What to do | | --- | --- | | *Save the qualification first — at AWS this lead is still {value}.* | Click **Save**, and convert once AWS confirms. | | *Only a Qualified lead can be converted. This one is {value}.* | Set the picker to **Qualified** and save. | | *This lead has already been converted.* | Nothing — use the **Converted Referral** card. | After a successful conversion a **Converted Referral** card appears in the Actions panel; **View** opens the new referral. ## Link a lead to an Opportunity or Account The **Opportunity** and **Account** cards attach the lead to your CRM records before or after conversion. **Link** opens a record picker (searchable by name — the Opportunity picker also shows Stage, Amount, and Close Date); **Edit** repoints an existing link. Saving one linkage preserves the other. An outbound lead's **Account** cannot be relinked: it is the Account the lead was enriched from, so the card shows the link with no **Link** or **Edit** button. Its **Opportunity** can be linked as usual. ## Enrich an Account into an AWS lead Enrichment works the other way round from an invitation: Fours sends one of your Salesforce **Accounts** to AWS Partner Central, AWS answers with what it already knows about that customer, and Fours creates a co-sell lead from the answer. The lead is **Outbound** in the **Direction** column, and you qualify and convert it like any other. ```d2 shape: sequence_diagram seller: "You, in Salesforce" suger: Fours aws: "AWS Partner Central" seller -> suger: "Create & enrich on the Account" suger -> suger: "Check the mapping, the 30-day rule, and the Account's website and contacts" suger -> seller: "If a check fails: the reason, under the button" { style.stroke-dash: 4 } suger -> aws: "Submit the Account and its contact as a lead" aws -> suger: "Readiness, marketplace and solution scores, customer profile" { style.stroke-dash: 4 } suger -> seller: "Lead card on the Account after a reload" { style.stroke-dash: 4 } ``` ### Where you enrich The controls are in the **Leads** section of the **Co-Sell** tab: - on an **Account** page, in **Suger Account Insights**, below the account's referrals; - on an **Opportunity** page, in the **Suger Opportunity Quick Panel**, below the referrals — for the Opportunity's Account. Leads are kept against the Account they were enriched from, so both places show the same leads for the same customer. A lead AWS sent you that is linked to the Account appears there too. ### Before you start - Your Fours admin has saved the lead-enrichment mapping in the Fours Console: on the **Co-Sell** page's **Settings** tab, under **Lead Enrichment** → **Lead Enrichment Mapping Configs** → **Salesforce Account → AWS Lead**. It maps the Account fields AWS needs: **Company Name**, **Website URL**, **Industry**, **Country Code**, and, for a US account, **State or Region**. Until the mapping is saved, the Leads section shows no **Create & enrich** or **Re-enrich** button. - The Account has a company name, a **Website**, and a country in the fields the mapping reads. Fours does not send an Account that lacks any of the three. - The Account has a contact Fours can name as the person AWS requires on every lead. If your admin set a **Primary contact field** in the mapping — an Account lookup to a Contact — and it names a contact that belongs to this Account and has an email address, that contact is used as-is. Otherwise Fours takes the most recently active contact whose email address is at exactly the website's domain. A subdomain does not count — a contact at `partner.acme.com` is not a match for `acme.com`. - You have AWS referral write access — see [Who can see and work leads](#who-can-see-and-work-leads). **Create & enrich** sends the one Account you are looking at, whether or not your admin has turned on scheduled enrichment in the Console. ### What the Leads section shows | State | What you see | | --- | --- | | **Never enriched** | A **No AWS lead** card explaining what enrichment returns, and a **Create & enrich** button — only when your org has saved the lead-enrichment mapping. | | **Enriched** | One card per lead. The lead name opens **Lead Detail (Suger)**. A card shows a readiness badge, the **Readiness**, **MP Engagement**, and **Solution Fit** tiles, **Solution category** and **Lead ID**, and an **AWS insights** block: Account name, Geography, Industry, Region, Program eligibility, Sub-industry, Sub-region, Segment, Company size, and Country. The first card ends with *Last enriched {date} · {n} days ago* and, when the mapping is saved, a **Re-enrich** button. | | **Enriched, no lead now** | *No co-sell leads to display* — *This account was enriched, but no co-sell lead is associated with it right now.* — with **Re-enrich** when the mapping is saved. | When the section loads, Fours checks whether your org has saved a Salesforce lead-enrichment mapping. Without one, every enrichment would be refused, so the section shows no **Create & enrich** card and no **Re-enrich** button; the same happens when the check cannot be completed. Leads that exist are still listed, because AWS sends inbound leads whether or not you enrich. When the Account has no leads either, the Leads section is not shown at all. The tiles appear only when AWS returned at least one of those scores, so a lead AWS sent you may show none, or only **Readiness**. ### Re-enrich once every 30 days An Account can be re-enriched once every 30 days. The help icon beside **Re-enrich** states the rule before you click — *AWS enrichment can be re-run once every 30 days. This account is eligible now.* or *… Available again on {date}.* — and the button stays disabled until that date. Fours enforces the same rule itself. ### After you click The section reads *Enrichment started. AWS is working on this account now; the lead appears here once it answers — reload the page in a few minutes.* A refusal shows its reason in red under the button instead. Reasons that come back from Fours start with a status code such as `[400]`: | Message | What to do | | --- | --- | | *Account not found, or you do not have access to it.* | Your Salesforce sharing does not give you this Account. Ask your Salesforce admin. | | *Salesforce Account {id} was not found, or the connected Salesforce user cannot read it* | The Integration User Fours connects as cannot see this Account. Ask your Salesforce admin to extend its access. | | *no lead-enrichment mapping is configured for this organization* | Ask your Fours admin to save the **Salesforce Account → AWS Lead** mapping. | | *this organization's lead-enrichment mapping predates the Salesforce Account source and must be re-saved before enrichment can run* | Ask your Fours admin to re-save the mapping on the Account source. | | *this account was enriched on {date}; re-enrichment is available again on {date}* | Wait until that date. When the last attempt did not produce a lead, the sentence starts *this account was checked on {date} and AWS returned no data* or *enrichment for this account failed on {date}* instead. | | *an enrichment is already in flight for this account; wait for it to finish before requesting another* | Reload in a few minutes. | | *this account cannot be submitted: this account has no website, …* | Fill in the Account's **Website**. | | *this account cannot be submitted: this account has no contact carrying an email address, …* | Add a contact with an email address to the Account. | | *this account cannot be submitted: none of the {n} contacts examined on this account has an email at the account's own domain* | Add or correct a contact whose email is at the Account's website domain. | | *this account cannot be submitted: AWS matches on company identity; this record is missing {fields}* | Fill in the Account fields the mapping reads for **Company Name**, **Website URL**, and **Country Code** — or ask your Fours admin to map fields that hold them. | | *this account cannot be submitted: AWS requires an ISO 3166-1 alpha-2 country code and "{value}" has no known translation; map the CountryCode column or set a fixed value* | Ask your Fours admin to map a field holding the two-letter country code, or to set a fixed value. | | *this account cannot be submitted: AWS requires a contact identity; the derived contact is missing {fields}* | Fill in the contact's missing first name, last name, or email in Salesforce. | | *this account cannot be submitted: AWS requires a business title on the contact, and the derived contact has none* | Fill in the contact's **Title** in Salesforce. | | *this account cannot be submitted: AWS requires a state or region when the country is US* | Fill in the state in the Account field the mapping reads for **State or Region**. | | *this account cannot be submitted: the industry value "{value}" has no AWS translation in this configuration* | Ask your Fours admin to add the value under **Industry Value Mapping** in the mapping. | The three contact checks apply to a re-enrichment as well. The last six apply only when the Account has no lead from an earlier enrichment: a re-enrichment works on the lead AWS already has rather than submitting a new one, so those six are skipped. If the section still shows no lead a few minutes after *Enrichment started*, the enrichment did not produce a lead in Fours — for example because AWS has not enabled partner-originated leads for your Partner Central account, a capability enabled on the AWS side, or because AWS already holds an engagement for this Account that Fours has no lead for. Ask your Fours admin to look into it, or contact support@suger.io. ### Working an enriched lead An enriched lead has no invitation to accept. It starts with **Invitation Status** `ACCEPTED` and **Qualification** **Open**, so you go straight to [qualifying](#qualify-the-lead) and [converting](#convert-to-an-opportunity) it. On its **Lead Detail (Suger)** page, the **Source record** section names the Account it was enriched from, and the **Account** card is read-only. ## Leads on the Opportunity page An opportunity's page shows leads in two places: the **Leads** section of the **Suger Opportunity Quick Panel**'s **Co-Sell** tab, which covers the Opportunity's Account and carries the [enrichment controls](#enrich-an-account-into-an-aws-lead), and the **Suger Cosell Leads Quick Panel** component, if you add it — see [Page Components](/salesforce-app/salesforce-app-page-components/). ## Who can see and work leads Lead API calls check your **AWS referral** permissions: reading the list, the detail, and the **Leads** section of the Co-Sell tab needs AWS referral read, and every action — accept, reject, qualify, convert, link, **Inbound Sync**, **Create & enrich**, and **Re-enrich** — needs AWS referral write. | Permission set | Lead records | Leads tabs | | --- | --- | --- | | Suger Integrator, Suger Integrator (Salesforce Integration License) | Read/write | Visible | | Suger User | Read/write | Visible | | Suger User - Cosell | Read/write | Visible | | Suger Cosell - AWS | Read/write | Visible | | Suger User - Read Only, Suger Cosell (Read Only), Suger Cosell - AWS (Read Only) | Read only | Visible | | Suger Cosell - Azure, Suger Cosell - GCP (and their Read Only variants) | No access | Visible | :::warning The Azure and GCP co-sell permission sets make the Leads tabs **visible without granting access to the Lead object**. A user holding only one of those opens the tab and sees nothing. Give them an AWS co-sell set — or `Suger User` — if they are meant to work leads. Marketplace-only permission sets do not carry the tabs at all. ::: ## Troubleshooting | Issue | Possible cause | Resolution | | --- | --- | --- | | **Leads V2 (Suger)** tab is missing from the navigation bar | The tab was removed from the app's navigation items, or your permission set does not include it | Add it back via **Setup → App Manager → Suger → Navigation Items**, and confirm your permission set is one of the co-sell or user sets above. | | The tab opens but the list is empty | Your org has no AWS leads yet, or your permission set grants the tab without the Lead object | Check the permission-set table above. Marketplace-only and Azure/GCP-only co-sell users cannot read leads. | | **Convert to Opportunity** is greyed out | The qualification is not saved as **Qualified**, an edit is still unsaved, or the lead was already converted | Read the reason written under the button. Set the picker to **Qualified**, click **Save**, and convert once the waiting notice clears. If a **Converted Referral** card is present the lead is already converted. | | The customer's name, email and phone are blank | The lead is still `PENDING` | AWS masks the invitation payload. The contact fields fill in after you accept. | | A lead's fields differ from the `Suger__Lead__c` record on a report | The tab reads live from Fours; the record is written by the periodic backfill | The tab is the current value. The record catches up on the next backfill run. | | A lead AWS sent minutes ago is not in the list | Fours pulls leads from AWS every three hours | Click **Inbound Sync**, wait a few minutes, then refresh. | | The **Leads** section of the Co-Sell tab reads *Couldn't load co-sell leads.* | You do not have AWS referral read access, or Fours could not be reached | Check your permission set against the table above, then reload the page. | | No **Create & enrich** or **Re-enrich** button, or no **Leads** section at all on the Co-Sell tab | Your org has not saved a Salesforce lead-enrichment mapping, or Fours could not read it. With no leads on the Account either, the section is hidden | Ask your Fours admin to save the **Salesforce Account → AWS Lead** mapping on the **Co-Sell** page's **Settings** tab, under **Lead Enrichment**, then reload the page. | | **Create & enrich** is refused, or no lead appears after *Enrichment started* | The Account has no Website or no contact at its domain, the 30-day window is still open, or the Account's company details do not meet AWS's requirements | See [After you click](#after-you-click) for each message and what to do. | | The **Account** card on a lead has no **Link** or **Edit** button | The lead is outbound: its Account is the one it was enriched from, and it cannot be changed | Nothing to fix. Link an **Opportunity** instead if you need one. | ## Related - [AWS Partner Central Leads](/cosell/cosell-leads/) — the same lifecycle in the Fours Console, including the unified lead statuses and how often Fours pulls leads from AWS. - [Custom Objects](/salesforce-app/salesforce-app-custom-objects/) — the `Lead__c` field reference, for reporting and automation. - [Create Co-Sell](/salesforce-app/salesforce-app-cosell/) — what happens to the referral a converted lead becomes. - [Permission Sets](/salesforce-app/salesforce-app-permission-sets/) — the full catalog behind the table above. --- Source: https://doc.fours.com/salesforce-app/ # Salesforce App The Fours App is a managed package you install from Salesforce AppExchange. Once it is connected, marketplace data lands in its own Salesforce custom objects — buyers, products, offers, entitlements, revenue records, referrals, and funding — normalized into one shape regardless of whether it came from AWS, Azure, GCP, or Snowflake. Your reps then create private offers, reseller authorizations, and co-sell referrals from an opportunity, and your ops team reports on all of it without exporting a CSV. This section is both the admin setup path and the reference for everything the package ships: the permission sets and custom permissions that decide who sees which button, the Lightning components and quick actions you place on record pages, the Apex invocable actions you call from Flow, the custom report types, and the OAuth model behind the connection. Setup is a one-time job; the rest of these pages you come back to. :::info Fours was formerly named Suger. Inside Salesforce, the package (Suger Connector) — its AppExchange listing, app, tabs, permission sets, components, quick actions and reports — still uses the name Suger until the package is renamed. ::: ## Start here 1. **[Install the Fours App](/salesforce-app/salesforce-app-install/)** — install from AppExchange, create a dedicated Integration User, and verify the two-way connection. 2. **[Assign Fours Permission Sets to Your Team](/salesforce-app/salesforce-app-assign-permission-sets/)** — until someone has a permission set, they see no Fours tabs or buttons at all. 3. **[Page Components](/salesforce-app/salesforce-app-page-components/)** — drop the Fours widget and detail cards onto your opportunity and record pages. 4. **[Create and manage a private offer](/salesforce-app/salesforce-app-offer/)** — the first thing most teams do from Salesforce once setup is done. ## Install and connect - **[Install the Fours App](/salesforce-app/salesforce-app-install/)** — the four-step install: package, Integration User, Salesforce-side configuration, and connecting Fours back to your org. - **[App Settings](/salesforce-app/salesforce-app-settings/)** — choose between V1 tabs (local Salesforce objects, sync-delayed) and V2 tabs (read live from Fours), add the Referrals tab, and control widget pinning. - **[Authentication & Security](/salesforce-app/salesforce-app-authentication-security/)** — the OAuth 2.0 authorization-code-with-PKCE flow, refresh-token rotation, token storage, and how to revoke access. ## Control who can do what - **[Assign Fours Permission Sets to Your Team](/salesforce-app/salesforce-app-assign-permission-sets/)** — the task version: pick the right set per person, assign it, and verify it took effect. - **[Permission Sets](/salesforce-app/salesforce-app-permission-sets/)** — the catalog: core roles, per-cloud co-sell and marketplace sets, funding, and add-ons. - **[Custom Permissions](/salesforce-app/salesforce-app-custom-permissions/)** — the finer layer beneath permission sets, including the rule that generic permissions override platform-specific ones. ## Put Fours on your Salesforce pages - **[Page Components](/salesforce-app/salesforce-app-page-components/)** — the panels and cards that live in the body of a record page and show linked offers, referrals, entitlements, and insights. - **[Quick Actions](/salesforce-app/salesforce-app-quick-actions/)** — the one-click buttons in the highlights panel at the top of a record, such as *New Offer via Suger* and *Co-Sell with AWS*. ## Work a deal from an opportunity - **[Create and manage a private offer](/salesforce-app/salesforce-app-offer/)** — build the offer, track its status, clone it, then extend, cancel, notify contacts, or download the EULA later. - **[Create Reseller Authorization](/salesforce-app/salesforce-app-cppo/)** — set the wholesale price for a channel partner (a CPPO); the reseller, not you, makes the final offer to the buyer. - **[Create Co-Sell](/salesforce-app/salesforce-app-cosell/)** — submit a referral to AWS, Azure, GCP, or Fours [partner-to-partner (PRM)](/prm/) from the opportunity, and create Salesforce records from a referral that arrived the other way. - **[Work AWS Co-Sell Leads](/salesforce-app/salesforce-app-leads/)** — accept the earlier-stage prospects AWS sends you, or enrich one of your Accounts into a lead, qualify them in the Leads tab, and convert a qualified lead into a co-sell opportunity. ## Report on and automate marketplace data - **[Reports](/salesforce-app/salesforce-app-reports/)** — the custom report types and pre-built reports that ship with the package, and how to build your own on top of them. - **[Custom Objects](/salesforce-app/salesforce-app-custom-objects/)** — the field-level reference for every object the package installs, and how they relate to one another. - **[Apex Actions](/salesforce-app/salesforce-app-apex-actions/)** — six invocable methods for Flow and Process Builder, covering share, fire-and-forget share, inbound response, linkage, an AWS referral update, and a shared-status check. - **[CRM Enrichment](/salesforce-app/salesforce-app-crm-enrichment/)** — push Fours engagement scores and marketplace metrics into custom fields on your own records, targeted with SOQL. ## Scope and limits :::info This section covers the managed package inside Salesforce. Configuring the Fours↔Salesforce connection itself — API credentials, field mapping rules, [sync preferences](/integrations/salesforce/#choose-what-backfills-to-salesforce) — lives in the [Salesforce integration guide](/integrations/salesforce/). Salesforce System Administrators bypass Fours permission sets entirely and always have full access; you do not assign them one. Not every capability spans every cloud. The custom objects hold data from AWS, Azure, GCP, and Snowflake, but the *Process Inbound Co-Sell Referral* Apex action covers Azure and AWS only, and several permission sets are scoped to a single cloud. ::: ## FAQ ### How does the AWS opportunity score show in Salesforce after the opportunity has been accepted and scored? It will appear on the referral record detail page. The field's API name is Suger\_\_AWS\_EngagementScore\_\_c, in case you'd like to set up any automation or formula fields. That field holds only AWS's own score for the opportunity, so a blank value means AWS has not scored it yet. Fours' own **Suger Predicted Engagement Score**, shown in the Fours widget, is not stored on the referral record, so it does not appear in reports built on this field. ### One field I’m having trouble setting up is the opportunity ID for partner CRM unique ID. It’s not letting me pull it up in the Salesforce field section. That field is mapped by default. So we do not need to set up mapping for it. ### Once the offer is created, the “Copy Offer URL” button on the offer object in Salesforce does nothing; why? Once an offer is created, you'll probably need to wait 3 to 5 minutes until it's actually created in the AWS Marketplace; only then will you be able to copy the link. Before that time, Fours will send the Offer data to AWS to create the offer. If you refresh the page after a few minutes, the Offer URL will be available in the Copy Button. ### Can we do Agreement-Based Offers (ABO) out of Salesforce, or do we need to use the Fours console? Yes, you can do it out of Salesforce. ### I am creating my first offer in Salesforce using Fours. Everything is filled out except for the API name. How can I find the API name? You have to define the API Name for your new dimensions. In this case, I would use the same dimension name but in lowercase and underscores instead of spaces. ### I created a referral directly in ACE, which has now been validated. Will that referral show up in Salesforce? If yes, how can I connect the referral I made in ACE to an opportunity that we have in Salesforce now? They will appear in your Salesforce the next time it's updated (e.g. after AWS accepts it or you manually edit something). If you could please put the Salesforce opportunity's ID into the "Partner CRM Unique Identifier" field, our system will make it show up in Salesforce and associate them together. ### The engagement score is showing on the referral in Salesforce; is it possible to have that field show up on the actual opportunity screen? If so, what steps would our team have to take to complete this? This is possible but must be done in your Salesforce instance. ### On the Fours <> Salesforce Integration, does it handle Public Offer Invoices? For example, if new customers purchase on AWS, will it send over that data (in any form) to Salesforce? Yes, we support auto-backfilling for Salesforce based on public offers. ### How do we sign up for and use the testing environment? You can easily create a testing environment connected to your Sandbox Environments within our platform. Once you set up your Fours Account here, you'll be able to add an additional environment associated with it. --- Source: https://doc.fours.com/hubspot-app/hubspot-app-configuration/ # Configuration Add the Fours App to your HubSpot Console. --- ## Overview After completing the integration with HubSpot, you need to add the Fours App card to your HubSpot console before you can start creating offers. The Fours app card is a panel that appears on your HubSpot deal records, letting your team create offers, resale authorizations, co-sell referrals, and AWS funding applications directly from a deal — without switching to the Fours Console or a cloud marketplace portal. The app also ships a second card, **Co-sell Insights**, which goes on company records instead of deals. :::danger - Make sure you have completed the integration with HubSpot first. Visit [Integration with HubSpot](/integrations/hubspot) for detailed instructions. ::: ## Prerequisites - You must complete the HubSpot integration in Fours Console before adding the app card. If you haven't done that yet, see [Integration with HubSpot](/integrations/hubspot). - You need **HubSpot Admin access** to customize deal record layouts. ## Add Fours App to your HubSpot console :::tip You can add the Fours app card to more than one view. Repeat these steps for any additional views your team uses — for example, if some reps use a custom view instead of the default one. ::: 1. Open a deal's detail page, click on "Customize record" link on top of this page > Customize record link on a HubSpot deal detail page 2. Go to "Record Customization" tab and click on "Default view" > Record Customization tab with Default view selected in HubSpot 3. Click on "Add cards" button on the view you want to add Fours to (taking Overview as an example) > Add cards button on the HubSpot deal record default view 4. In the panel that opens, click **Apps** to filter the available cards, then find the Suger App and select it. > Suger App card selection filtered by Apps in HubSpot 5. You can drag the Suger App to the top for better visibility — your team will use it frequently. > Dragging the Suger App card to the top of the layout 6. Click on "Save and exit" button, and you can start using the Fours App. The card will now appear on all deal records that use this view. > Save and exit button after adding the Suger App card > Suger App card displayed on a HubSpot deal record 7. You are all set! ## Add the Co-sell Insights card to your company records The Fours app ships a second card, **Co-sell Insights**, and it is registered on the **companies** object rather than on deals. Adding the Fours deal card does not add it — you have to add it to a company record layout separately. 1. Open a company record, click **Customize record**, and pick the view you want to change. 2. Click **Add cards** on that view, click **Apps** to filter, and select **Co-sell Insights**. 3. Click **Save and exit**. :::tip The two cards are independent. If your team only works deals, the deal card on its own is enough; add **Co-sell Insights** when you also want co-sell context on the company record. ::: ## Verify the app card is working Open any HubSpot deal record and confirm the Suger app card appears on the page. The Suger panel shows five tabs — **Offers**, **Entitlements**, **Co-Sell**, **Funding**, and **Insights** — and up to four action buttons across the top: **New Offer**, **New Resale**, **New Funding**, and **Co-Sell**. Not every button appears for every organization. **New Funding** is AWS-only and requires an AWS ACE (Partner Central) integration, and the **Co-Sell** button only lists the destinations your organization has connected — so a card with fewer buttons is not necessarily broken. If the card is not visible after saving: - Confirm the HubSpot integration is verified in Fours Console → **Settings** → **Integrations** → **HubSpot**. The status should show **Verified**, not **Created**. - Check that you saved and exited the record customization — the card will not appear until you click **Save and exit**. - Try a hard refresh — **Cmd+R** on Mac or **Ctrl+Shift+R** on Windows. ## Troubleshooting | Issue | Possible cause | Resolution | | --- | --- | --- | | Suger does not appear in the Apps list | The HubSpot integration has not been completed or verified | Complete the HubSpot integration first. The status in Fours Console must be **Verified** before the app appears | | App card was added but is not visible on deal records | The page was not saved after customization | Go back to **Customize record** and confirm the Suger card is in the layout, then click **Save and exit** | | App card appears but shows an error or blank state | The integration connection has been disrupted | Go to Fours Console → **Settings** → **Integrations** → **HubSpot** and click **Verify** to re-verify the connection | | App card is only visible to some users | The customization was applied to a view not all users see | Check which view each user's profile defaults to and apply the customization to that view as well | ## Frequently Asked Questions ### Do I need to add the Fours app card to every deal individually? No. Adding the card to a view applies it to all deal records that use that view — you only need to do it once per view. ### Can I add the Fours app card to views other than the default Overview? Yes. Repeat the steps above for any other views your team uses. Each view is customized independently. ### What's the difference between the HubSpot integration and the Fours app card? The integration connects Fours to your HubSpot account at the system level — it gives Fours permission to read and write deal data. The app card is the UI element that lets your team interact with Fours from inside a deal record. Both are required. The integration comes first; the app card comes second. --- Source: https://doc.fours.com/hubspot-app/hubspot-app-offer/ # Create Offer Easily create private offers directly from a HubSpot deal using the Fours App. --- ## Overview A private offer is a custom deal you send to a specific buyer through a cloud marketplace — AWS, Azure, or GCP. It includes your negotiated pricing, contract terms, and expiration date. The buyer receives a link to review and accept the offer directly in their cloud marketplace account. Once the buyer accepts it, the contract is live and billing starts automatically through the marketplace. After adding the Fours App to your HubSpot Console, you can create these offers straight from a deal, without leaving HubSpot. For more details on offers, see [Understand Marketplace Offers](/concepts/resources/#marketplace-offers). ## Prerequisites - The Fours App must be set up in HubSpot and the Fours app card must be visible on your deal pages. If you haven't done that yet, see [Configuration](/hubspot-app/hubspot-app-configuration/). - The product you want to create an offer for must already exist in Fours. If it doesn't, create it in the Fours Console first before continuing. ## Create an offer 1. Navigate to the deal's detail page and click the **"Suger"** tab at the top of the page. > Suger tab on the HubSpot deal detail page 2. Locate and click the **"New Offer"** button. > New Offer button in the Suger panel 3. The **Create Private Offer** panel opens with **"Choose the type of offer you wish to create."** Pick one of the three types: | Option | Use it when | | --- | --- | | **Private Offer** | You are sending a new negotiated offer directly to an end customer | | **Amendment Offer** | You are changing an offer or agreement that already exists | | **Reseller Offer** | You are creating the offer as a reseller, based on an authorization an ISV granted you | :::tip **Reseller Offer** here is the reseller side of the transaction. If you are the ISV authorizing a reseller to sell on your behalf, use the **New Resale** button instead — see [Create CPPO](/hubspot-app/hubspot-app-cppo/). ::: 4. Choose the product on which the private offer will be based. The product list shows only products available in your Fours account. > Product selection for creating a private offer 5. Complete the required fields in the form. Note that the required fields may vary depending on the cloud marketplace and the type of offer. > Private offer form with required fields :::tip If field mapping has been configured, the form will be prefilled with corresponding fields from the HubSpot deal, making the offer creation process faster and easier. Review the prefilled values for accuracy before submitting. ::: 6. Once all necessary information is filled in, submit the form to create the offer. > Completed offer form ready to submit :::warning After submitting, wait 3–5 minutes before copying the offer link. Fours sends the offer data to the cloud marketplace immediately, but the marketplace takes a few minutes to process it. The offer URL is not available until the marketplace confirms the offer. Refresh the offer record after a few minutes and the link will be ready. ::: 7. You are all set! ## Contacts on the offer The AWS offer forms and the Azure private-offer forms (SaaS, Flat Rate, Per User and virtual machine products) have a **Contacts** section. Enter a **Contact Name** and **Contact Email** and click **+ Create Contact**, or click **Or, add existing contacts** and pick from the deal's HubSpot contacts in **Select Contacts**. The contacts are saved on the Fours offer, and Fours emails them only through the **Offer Notification Contacts** rule in your [email notification settings](/settings/email-notification/#email-an-offers-contacts). On Azure these contacts replace the form's old **Notification contacts** list of email addresses, and they are not sent to Microsoft. The Azure **New Resale** forms keep their email list. ## AWS: buyer net payment term Every AWS offer form — SaaS, agreement-based, container, machine learning, professional services, and reseller — carries a **Buyer net payment term** field. It sets how long the buyer has to pay after being invoiced. Leave it on **Customer's net terms with AWS** and nothing changes: the buyer keeps whatever terms they already have with AWS. Choose a custom term and you pick one of six: | Option | | | --- | --- | | Net 15 days | Net 60 days | | Net 30 days | Net 90 days | | Net 45 days | Net 120 days | :::warning Use a custom term only after explicitly agreeing it with the buyer, and note three limits: it applies only to **pay-by-invoice** buyers, AWS may charge a credit-card buyer immediately regardless, and **a released term cannot be changed**. Longer terms also delay your own disbursement. ::: Once the offer exists, the term is shown on the offer detail as **Buyer payment term**. ## AWS: pre-authorized renewal terms The AWS SaaS, container and professional-services offer forms carry a **Configure renewal terms** section for [pre-authorized auto-renewal](/aws-marketplace/pre-authorized-auto-renewal/). It appears whenever the selected product has at least one commit (contract) dimension. A product that also meters usage qualifies too — only the commits matter. - **Container offers** also need a committed pricing model. On a usage-based or free pricing model, or for a product that is free only, the section stays hidden. - **AMI products never show it.** The container offer form also handles AMI products, and for them it leaves the section out: AWS offers no auto-renewal on an AMI product. - **No commits, no renewal term.** If you switch to a product without commits, any renewal term the form was carrying — for example from a draft — is dropped, so it is never submitted. What each renewal option means is covered in [Pre-Authorized Auto-Renewal](/aws-marketplace/pre-authorized-auto-renewal/). Once the buyer accepts, you manage the renewal from the deal's **Entitlements** tab — see [Adjust the renewal uplift](/hubspot-app/hubspot-app-entitlements/#adjust-the-renewal-uplift). ### Choose a renewal option On a new offer the section starts on **No renewal**. Each option is a card of its own, and the fields for the option you pick open inside its card: | Option | What it does | | --- | --- | | **No price uplift** | Renew at the same price each cycle. | | **Price uplift** | Increase pricing each cycle by a **Fixed percentage** — the **Price increase percentage**, 0 to 100 — or within a **Percentage range** set by a **Minimum**, **Maximum** and **Default uplift percentage**. | | **No renewal** | Do not include auto-renewal terms with this offer. | **Percentage range** prefills a **Minimum** of 5%, a **Maximum** of 30% and a **Default uplift percentage** of 10%, so adjust the band to the one you agreed with the buyer. It also fills in the **Adjustment deadline** (**Days before agreement expiration**) with 30 days more than the renewal decision deadline — so the uplift is settled 30 days before the opt-out decision closes — or with 30 days when the renewal decision deadline is blank. Both renewing options then ask for the **Renewal decision deadline** and the **Renewal count** — **Definite**, with a **Number of renewals**, or **Indefinite**. On an offer that bills in installments, they also carry a renewal payment schedule. ### Renewal decision deadline **Renewal decision deadline (optional)** replaces the field that used to be called **Lockout period**. It is the number of days before the agreement expires after which neither party can opt out of the renewal. It opens empty: left blank, the deadline is the agreement expiration date. If you set it, it must be at least 1 day, and on a percentage range the adjustment deadline must be greater than it. **Both deadlines must land inside the contract term.** Each is counted back from the end of the contract, and the form works out the calendar date it lands on. A deadline that falls outside the term stops the offer before it is sent, with an alert that names the date and the term — for example: > *Renewal decision deadline (800 days) falls on 2025-07-23, which is not inside the contract term (2026-10-01 → 2027-10-01).* The same check applies to the **Adjustment deadline**. The contract term is read from real dates: the term length — in days, months or years — added to the offer's start date, or the start and end dates when you set the term by dates. A 12-month term from 2026-10-01 ends on 2027-10-01, 365 days later. When the offer has no start date because its term starts when the buyer accepts, the term is counted from today. :::warning The check now runs on the SaaS, container and professional-services forms alike — the container and professional-services forms had none before. A saved draft whose deadline reaches outside its contract term now stops at the form until you shorten the deadline — such an offer used to be refused only after you submitted it. ::: ### Renewal payment schedule The renewal payment schedule sets how each renewed term is invoiced — up to **86** installments, totaling 100%. It has no switch of its own. On a SaaS or professional-services offer it appears with **Enable Payment Installments**, and turning that switch off removes it; on a container offer, choosing the **Contract pricing with installment plan** pricing model makes it appear. **It starts as a copy of the offer's own installments.** Each installment you entered for the initial term becomes a row at the same point in the renewed term, with the same share of the total, and each row keeps its own day of the month — installments on 30 September, 31 December, 31 March and 30 June stay on those month ends. The rows count months of the agreement from the offer's start date. With a 15 October start, an installment on 1 November still falls in the agreement's first month, so it becomes the *Agreement start date* row, with **Day of month** 1. An offer with no start date — its term starts when the buyer accepts — counts from its earliest installment, which becomes the *Agreement start date* row. Either way, twelve monthly installments that begin in the agreement's first month fill *Agreement start date* through *Month 11 of the agreement*. A few cases read differently: - If two installments fall in the same month — the same month of the agreement on an offer with a start date, the same calendar month on one without — the rows are timed in exact days rather than months. - Installments on the same date become one row. - If an installment's date is missing or invalid, an amount is missing or negative, or the amounts total zero, the schedule is a single row: 100% at the agreement start. - A row that falls in the contract's last month gets no day of its own; see **Day of month** below. While the schedule is still exactly what was copied, changing the offer's installments or its start date copies them again. Once you edit a row, your schedule is kept as you left it, and a draft reopened with a saved schedule keeps that schedule, apart from any day saved on the last month's row, which is cleared. ```d2 direction: right noschedule: "No renewal\npayment schedule" seeded: "Filled from the\noffer's installments" edited: "Kept as you\nedited it" noschedule -> seeded: "the offer bills\nin installments" seeded -> seeded: "installments or start\ndate change: filled again" seeded -> edited: "you edit a row" seeded -> noschedule: "Enable Payment Installments off\n(SaaS or professional services)" {style.stroke-dash: 4} edited -> noschedule: "Enable Payment Installments off\n(SaaS or professional services)" {style.stroke-dash: 4} ``` Each row has: | Field | What it holds | | --- | --- | | **Months after agreement start** or **Days after agreement start** | When the installment is due. The timing in words sits underneath — for example *Agreement start date*, *Month 3 of the agreement* or *45 days after the agreement starts*. | | **Day of month (optional)** | The billing day, on a schedule timed in months. On the row in the contract's last month — *Month 11 of the agreement* on a 12-month or 1-year term, the *Agreement start date* row on a 1-month term — the field is locked and reads **Start day**: AWS bills that installment on the same day of the month the renewal starts and doesn't allow a custom day there. The lock applies only when the term is a length in months or years; with a term set by dates, or a length in days, every row keeps its day. | | **Percentage of TCV** | The row's share, 0.01 to 100 with at most two decimal places | | **Estimated first renewal cycle payment amount** | Shown when the offer's installments carry amounts: the row's share of the first renewal cycle — the contract total after one cycle of uplift, at the fixed percentage or the range's default — in the offer's currency. The rows add up exactly to that cycle's total. | When the installments carry amounts, **Original contract total** and **Contract duration** appear above the rows — the figures the rows are priced against. The duration reads, for example, *12 months · 365 days*, or *12 months · Starts when the buyer accepts* for an offer whose term starts on acceptance. - **Due date calculation** — **By month** or **By exact days** — sets the unit for the whole schedule; rows no longer carry a unit of their own. Switching it converts every row at 30 days to a month. - **Renewal Payment Scheduler** generates equal installments from a **Payment frequency** (Monthly, Quarterly, Semi-annually, Annually or Custom), a **Due date calculation**, a **Number of installments** (up to 86) and, when timed by month, an optional **Day of month**. Check the **Plan preview**, then click **Create** to replace the rows. On a term in months or years, the **Day of month** hint reminds you that the last month always bills on the renewal start day, and the preview marks that row *renewal start day*. - **New payment installment** adds a single row. Underneath, the schedule counts its installments and shows the **Allocated** and **Remaining** percentages. On a term that is a length in months or years, Fours refuses a row timed in months that falls after the term's last month — *Month 12 of the agreement* or later on a 12-month term, which a **Renewal Payment Scheduler** plan of 13 monthly installments would produce — when you submit, with an error that names the row. ## Azure: automatic subscription activation An Azure SaaS offer form carries **Automatically activate the subscription on purchase**. - **Checked** — Azure activates the SaaS subscription automatically once the customer purchases the offer. - **Unchecked** — your team activates it. The checkbox appears only when your Azure integration is set to **self-managed subscription activation** and the offer uses **V2 pricing**. On any other combination it is hidden, because the setting cannot be carried on the offer at all. See [Azure Marketplace integration settings](/azure-marketplace/integration/). ## Azure: custom contract terms and renewal On an Azure offer, the **Contract Duration** toggle includes a **Custom** option. Choosing it reveals two more fields: - **Custom Duration Unit** — months or years. - **Custom Duration Value** — the length. The helper text is *"1–120 months or 1–10 years; month values divisible by 12 must use years"*, so a 24-month term has to be entered as 2 years. A custom term also makes **Renewal Behavior** required, and its "no renewal" option is hidden — Azure will not accept a custom-term offer without a renewal decision. The options are: | Renewal Behavior | What happens at the end of the term | | --- | --- | | **No renewal configured** | The subscription does not renew. Not available when the term is custom | | **Renew into private offer** | The customer rolls into the private offer pricing again | | **Renew into public offer** | The customer rolls onto your public marketplace listing pricing | When you pick a renewal that continues the subscription, set **Renewal Contract Duration** and **Renewal Billing Frequency** underneath it. Two defaults are worth knowing, because they changed: - Choosing **Custom** now pre-selects **Renew into public offer**. If you want the customer to roll into the private pricing again, change it yourself — the form no longer assumes it. - **Renewal Contract Duration** is seeded with the **shortest** published term on your base plan, and the dropdown is ordered shortest first. ## GCP: usage plan pricing model When the plan you pick for a GCP offer is a usage plan, the form asks for a **Usage Plan Pricing Model**. Until you choose one, its description reads *"Select the pricing model for the usage plan."* Once you do, the description shows the hint GCP's Producer Portal gives for that model: | Usage Plan Pricing Model | Description once selected | | --- | --- | | **Commitment discount with additional usage at list price** | *The customer promises to pay a discounted amount. All usage, including overages, is list price.* | | **Commitment with all usage discounted** | *The customer promises to pay an amount. All usage, including overages, is discounted.* | | **Usage-based discount only** | *The customer pays a discounted amount for what they use* | The field appears on every GCP form that prices a usage plan: a **Private Offer**, an **Amendment Offer**, and a resale authorization created with **New Resale**. On an amendment, keep the model of the offer you are replacing — GCP refuses an amendment that changes it. The form fills the model in from that offer when it can; if the field is empty, choose the model the original offer uses. How each model charges for usage is explained in [Usage-Based Offers](/gcp-marketplace/create-private-offer/#usage-based-offers). ## GCP: expiry within three months Google Cloud Marketplace requires an offer to expire within three months. On a GCP offer that limit applies to the **Expiry Date**, and on a GCP resale authorization to the **Acceptance Due Date**. The date picker still lets you choose a later date, but Fours refuses the offer when you submit it, before anything is sent to Google, and the error alert names the date you picked and the last one you can use — for example: > *the offer expiration date (January 5, 2027) is too late. Google Cloud Marketplace requires offers to expire within 3 months, so choose a date on or before December 22, 2026* Pick that date or an earlier one and submit again. Saving a draft does not check the date; the check runs when you submit. How the last allowed date is worked out is covered in [Set pricing information](/gcp-marketplace/create-private-offer/#step-3-set-pricing-information). ## Manage an offer after it is created Each row in the **Offers** tab has an actions menu: | Action | What it does | | --- | --- | | **Cancel Offer** | Cancels the offer so the buyer can no longer accept it | | **Extend Expiry Date** | Pushes the offer's expiry date out | | **Edit Offer Info** | Edits the offer's descriptive information | | **Clone Offer** | Starts a new offer pre-populated from this one. Not available on resale authorizations (`CPPO`) or on an incoming reseller offer (`CPPO_IN`) | | **Edit draft** | Reopens an offer that never reached the marketplace so you can correct and resubmit it. Shown on `DRAFT`, `CREATE_FAILED`, and `INVALID` offers | ### When Extend Expiry Date is available **Extend Expiry Date** is offered when the offer's status is one of: | Status | Why it is extendable | | --- | --- | | **PENDING_ACCEPTANCE** | The buyer has not accepted yet and needs more time | | **EXPIRED** | The offer lapsed and you want to revive it | | **UPDATE_FAILED** | A previous extend attempt failed — extend again to retry it | It is never available in these cases: - **CPPO offers.** A CPPO is created and owned by the reseller, so the ISV cannot extend it. - **AWS resale authorizations (CPPO_OUT).** AWS does not support extending an authorization. - **Azure offers on v1 pricing.** Only v2 and v3 Azure pricing can be extended. - **Azure resale authorizations.** They have no expiry date to extend — see [Azure: grant a resale authorization](/hubspot-app/hubspot-app-cppo/#azure-grant-a-resale-authorization). ## GCP: replaced offers When a GCP offer replaces an earlier one, the offer detail shows **Replaced Offer ID** — the identifier of the offer it supersedes. Once Fours resolves that identifier, a **Replaced Offer** row appears with the replaced offer's name, so you can see at a glance which offer this one took over from. ## GCP: dates in Pacific time On a GCP offer's detail, **Start Date**, **Expire Date**, **Accept Date** and **End Date** show a date and time in Pacific time, with PST or PDT — for example *8/31/2026, 11:45:00 PM PDT* — rather than a UTC date. Pacific time is the calendar GCP Marketplace keeps, so the dates line up with GCP's Producer Portal. Fours also counts a GCP term from the Pacific calendar day it starts on. An offer whose term starts when the buyer accepts, and that was accepted in the Pacific evening, no longer shows an end date one day later than the Producer Portal. The **Offers** table still lists **Create (UTC)** and **Expire (UTC)** in UTC, so a GCP offer's expiry can read one day later there than in the offer detail. ## What happens next After you submit the offer: - Fours creates the offer and links it to the HubSpot deal. - The offer is sent to the cloud marketplace for processing. - Once the marketplace confirms the offer, the offer status updates and the offer URL becomes available. - Copy the offer URL and send it to the buyer — they use it to review and accept the offer in their cloud marketplace account. - The offer is also visible in the Fours Console under your offers list. ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | No Suger tab visible on the deal page | The Fours app card has not been added to the deal layout | Follow [Configuration](/hubspot-app/hubspot-app-configuration/) to add the app card | | No New Offer button visible inside the Suger panel | The HubSpot integration connection has been disrupted | Go to Fours Console → Settings → Integrations → HubSpot and click Verify to re-verify the connection | | Product list is empty | No products have been set up in Fours | Confirm that products exist in the Fours Console before creating an offer | | Form fields are blank — not pre-filled from the deal | Field mapping has not been configured | Field mapping is an optional admin setup. Contact your admin to configure it | | Offer URL is not available after the offer is created | The marketplace has not finished processing the offer yet | Wait 3–5 minutes and refresh the page. The URL appears once the marketplace confirms the offer | | An error alert says *the offer expiration date (…) is too late* when you submit a GCP offer | The **Expiry Date** is more than three months away, which Google Cloud Marketplace does not accept | Pick the date the message names, or an earlier one, and submit again — see [GCP: expiry within three months](#gcp-expiry-within-three-months) | | An error alert says *… is past the last month of the renewal agreement* when you submit an AWS offer | A row in the renewal payment schedule is timed after the contract's last month — *Month 12 of the agreement* or later on a 12-month term | Move the row into the term, or rebuild the schedule with fewer installments, and submit again — see [Renewal payment schedule](#renewal-payment-schedule) | | Offer was created but is not visible on the deal | Sync between Fours and HubSpot is delayed | Refresh the page after a few minutes. If it still doesn't appear, confirm the offer was created successfully in the Fours Console | ## Frequently asked questions **Can I create offers for AWS, Azure, and GCP from HubSpot?** Yes — as long as products are set up for each cloud in Fours. The product selector in the offer form shows all available products across clouds. **What is field mapping and do I need it?** Field mapping is an optional configuration that automatically pre-fills offer form fields with data from the HubSpot deal — like company name, deal value, or close date. It saves time and reduces manual entry errors. You can still create offers without it, but you'll need to fill in all fields manually. **Will the offer show up in the Fours Console too?** Yes. Any offer created from HubSpot is also visible in the Fours Console under your offers list. **The buyer can't find the offer link. What do I do?** Open the offer in HubSpot or in the Fours Console and copy the offer URL directly. Make sure at least 3–5 minutes have passed since the offer was created — the URL is not available until the marketplace confirms it. --- Source: https://doc.fours.com/hubspot-app/hubspot-app-cppo/ # Create CPPO Create a reseller authorization (CPPO) directly from a HubSpot deal using the Fours App. --- ## Overview A reseller authorization — also called a Channel Partner Private Offer (CPPO) — is how you give a reseller or channel partner permission to sell your product on a cloud marketplace on your behalf. In plain terms: - You (the ISV) create a reseller authorization that sets the price you're willing to give the reseller. On Azure you can instead grant a standing [resale authorization](#azure-grant-a-resale-authorization), which carries no price. - The reseller then creates their own private offer to the end customer, using your authorization as the basis — at whatever markup they choose. - The end customer buys from the reseller through the marketplace, and billing flows through accordingly. :::info A reseller authorization is not sent to an end customer — it is sent to the reseller. Make sure the deal you create it from is associated with a reseller, not the end customer. ::: For more details, see [Channel Partner Private Offers (CPPO)](/aws-marketplace/cppo/) for AWS and [Azure CPPO](/azure-marketplace/cppo/) for Azure. ## Prerequisites - The Fours App must be set up in HubSpot and the Fours app card must be visible on your deal pages. If you haven't done that yet, see [Set up the Fours App in HubSpot](/hubspot-app/hubspot-app-configuration/). - The product you want to authorize must already exist in Fours. If it doesn't, create it in the Fours Console first before continuing. ## Create a reseller authorization 1. Open the HubSpot **Deal** record associated with your reseller, then click the **"Suger"** tab at the top of the deal page. > Suger tab on a HubSpot deal record page 2. Locate and click the **"New Resale"** button inside the Suger panel. > New Resale button inside the Suger panel in HubSpot 3. Under **"Select the product on which the resale authorization is based"**, choose the product. The list shows only products available in your Fours account. > Product selection step for reseller authorization 4. Complete the required fields in the form. Note that the required fields may vary depending on the cloud marketplace and product type. On AWS, this is where you pick the reseller — see [Choose the reseller account on AWS](#choose-the-reseller-account-on-aws) below. On Azure, this is where you choose the **Private Offer Type** — see [Azure: grant a resale authorization](#azure-grant-a-resale-authorization) below. > Reseller authorization CPPO form fields :::tip If field mapping has been configured, many fields will be pre-filled from the HubSpot deal automatically — review them for accuracy before submitting. ::: 5. Once all necessary information is filled in, submit the form to create the reseller authorization. > Submit button on the reseller authorization form 6. You are all set! ### Cap the reseller's payment terms The AWS resale form has a **Maximum buyer net payment term** field. It sets the longest net payment term the channel partner is allowed to offer their buyer — the partner can choose that term or anything shorter, but not longer. Leave it on **No custom maximum** and the reseller gets no custom-term authorization at all: on their own offer the field is disabled and reads *"The ISV did not authorize custom net payment terms."* Like the buyer term itself, a released maximum cannot be changed. Separately, the AWS resale form's **commit term length** — how long the authorized commitment runs — accepts 1 to 144 months for SaaS (contract or subscription) products and 1 to 60 months for every other product type; a value over the cap is rejected with *"Maximum N months"*. This is measured in months and is a different field from the **Maximum buyer net payment term** above, which is measured in days. ## Choose the reseller account on AWS On the AWS resale form, the reseller is picked from a single **Reseller Account** dropdown. Fours keeps a crawled list of known AWS reseller accounts, and the dropdown searches it for you — its description reads *"Search by reseller name or 12-digit AWS account ID."* 1. Open the **Reseller Account** dropdown and type part of the reseller's name, or its 12-digit AWS account ID, into the dropdown's own search box — there is no separate filter field. 2. The list is capped — 100 entries before you type, 200 once you are searching. When more resellers match than that, the field's description reads *"Showing {n} of {m} — search by reseller name or 12-digit AWS account ID."* Keep typing until your reseller appears, then select it. **Add reseller manually** sits right beside the dropdown, for a reseller that is genuinely not in the list — see below. ### Add a reseller manually If the reseller is genuinely not in the list, click **Add reseller manually**, beside the **Reseller Account** dropdown. The modal asks for two things: | Field | Required | Rules | | --- | --- | --- | | **AWS account ID** | Yes | Exactly 12 digits. Anything else is rejected with *"AWS account ID must be exactly 12 digits."* | | **Display name** | No | A label so you can recognize the reseller later. At most 128 characters, otherwise *"Name must be at most 128 characters."* | Three things to know before you use it: - **A manual entry wins a collision.** If the account ID you add is also in the crawled AWS list, your entry takes precedence and is listed first — so a careless display name renames that reseller for everyone in your organization. - **The display name never leaves Fours.** It is local to your organization and is not sent to AWS. AWS only ever sees the account ID. - **The account is not verified against AWS.** Fours checks the format, not that the account exists or is a valid reseller. A typo produces an authorization pointed at the wrong account. :::warning If the panel shows *"The reseller list could not be loaded, so known resellers may be missing. Reopen this panel to retry before adding one manually."*, the dropdown being empty does not mean your reseller is unknown — the list simply failed to load. Close and reopen the panel to retry before adding an account by hand. ::: ## Azure: grant a resale authorization On an Azure product, the **New Resale** form asks for a **Private Offer Type**. Alongside the two private-offer types — **Multiparty private offers**, and **Private offers with CSP margin-sharing**, which is not offered for container products — there is a third option: **Resale authorization**. **Resale authorization** is offered only for SaaS and virtual machine products — Microsoft supports resale-enabled offers for no other product type — so a container product offers **Multiparty private offers** alone. A draft that already holds a resale authorization keeps the option. A resale authorization is a standing grant, not a private offer. You authorize one resale partner to sell the product on your behalf in the customer markets you choose, and the partner then creates their own private offers for it in Partner Center. It has no pricing, dates or terms of its own, and you can revoke it at any time. ```d2 direction: right hubspot: "HubSpot deal\n(New Resale)" suger: "Fours" pc: "Microsoft\nPartner Center" partner: "Resale partner" hubspot -> suger: "seller ID +\ncustomer markets" suger -> pc: "resale authorization" partner -> pc: "creates own private offers\nin those markets" ``` Choosing **Resale authorization** cuts the form down to **Offer Name**, a **Resale authorization** section and **Internal Notes** — there are no partner, customer, date, pricing, EULA or renewal fields. The section asks for two things: | Field | Required | What to enter | | --- | --- | --- | | **Resale partner's seller ID** | Yes | The Partner Center seller ID of the partner you are authorizing. The partner finds it in Partner Center under **Account settings** → **Identifiers**, in their organizational profile. | | **Customer markets** | Yes, at least one | The markets where the partner may sell the product, each listed by country name and code. Seven markets are never offered, because Microsoft does not support resale in them: Brazil, Belarus, India, South Korea, Mexico, Russia and Singapore. | If either is missing, the form stops with *"Please enter the resale partner's seller ID."* or *"Please select at least one customer market."* ### What Fours checks when you submit When you click **Create Offer**, Fours checks three things before sending the authorization to Microsoft: - **The product is published on Azure Marketplace.** A product that has not been published there yet, or that is still a draft, pending, restricted or failed to create, is refused. - **The partner has no other live or in-progress authorization for the product.** Fours refuses a second authorization for the same partner and product while an existing one is `PENDING_CREATE`, `CREATE_SUCCESS`, `ACTIVE` or `PENDING_CANCEL`. A `DRAFT`, a `CREATE_FAILED` or a revoked (`CANCEL_SUCCESS`) authorization does not block a new one. - **The seller ID is looked up in Partner Center.** If Partner Center reports the seller ID as not found, the submission is refused. If the lookup cannot run or fails, Fours submits the authorization and Microsoft decides whether it succeeds; a failure Microsoft reports shows as `CREATE_FAILED` on the **Offers** tab. When Fours refuses a submission, an alert on the panel gives the reason. ### After it is created - **The partner and markets are not shown in HubSpot.** The HubSpot offer detail does not list them. Open the authorization in the Fours Console, where it shows **Customer Markets** and **Authorization Status**. - **There is no expiry to extend.** **Extend Expiry Date** is never offered on a resale authorization. - **Revoke it with Cancel Offer.** Once its status is `ACTIVE`, **Cancel Offer** in the offer's actions menu revokes it. A revoked authorization shows `CANCEL_SUCCESS`. For the same flow in the Fours Console, see [Create a Resale Authorization](/azure-marketplace/cppo/#create-a-resale-authorization). ## The other way in: Reseller Offer **New Resale** is the ISV-side action — you authorize a reseller. The reseller side of the same transaction is a **Reseller Offer**, which is one of the three options inside the **New Offer** panel, alongside **Private Offer** and **Amendment Offer**. Use it when you are the reseller creating the final offer to the end customer from an authorization someone granted you. See [Create Offer](/hubspot-app/hubspot-app-offer/). ## What happens next After you submit the reseller authorization: - Fours creates the authorization and links it to the HubSpot deal. - The authorization is sent to the cloud marketplace for processing. - Once confirmed by the marketplace, the reseller receives access to the authorization and can create their own private offer to the end customer. - You can track the status of the authorization from the deal record in HubSpot or in the Fours Console under your offers list. ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | No Suger tab visible on the deal page | The Fours app card has not been added to the deal layout | [Set up the Fours App in HubSpot](/hubspot-app/hubspot-app-configuration/) to add the app card | | No **New Resale** button visible inside the Suger panel | The HubSpot integration connection has been disrupted | Go to Fours Console → **Settings → Integrations → HubSpot** and click **Verify** to re-verify the connection | | Product list is empty | No products have been set up in Fours | Confirm products exist in the Fours Console before creating a reseller authorization | | The reseller is not in the **Reseller Account** dropdown | The list is capped, or it failed to load | Type more of the reseller's name or account ID into the dropdown's search box to narrow the capped list. If the "could not be loaded" notice is showing, reopen the panel to retry before adding the account manually | | Form fields are blank — not pre-filled from the deal | Field mapping has not been configured | Field mapping is an optional admin setup. Contact your admin to configure it | | An error alert says *the offer expiration date (…) is too late* when you submit a GCP resale authorization | The **Acceptance Due Date** is more than three months away, which Google Cloud Marketplace does not accept | Pick the date the message names, or an earlier one, and submit again — see [GCP: expiry within three months](/hubspot-app/hubspot-app-offer/#gcp-expiry-within-three-months) | | Reseller authorization was created but is not visible on the deal | Sync between Fours and HubSpot is delayed | Refresh the page after a few minutes. If it still doesn't appear, confirm the authorization was created in the Fours Console | ## Frequently Asked Questions (FAQs) **Q: What's the difference between a reseller authorization and a private offer?** A private offer goes directly to an end customer. A reseller authorization goes to a channel partner (reseller), who then creates their own private offer to the end customer. Use a reseller authorization when you're selling through a partner, not directly to the buyer. **Q: Does the reseller see my cost price when I create a reseller authorization?** Yes — the reseller sees the price you set in the authorization. They can then mark it up when creating their own offer to the end customer, but they cannot go below the price you've authorized. An Azure [resale authorization](#azure-grant-a-resale-authorization) is the exception: it carries no price at all. The partner creates their own private offers for your product in Partner Center. **Q: Can I track whether the reseller has acted on the authorization?** Yes. You can check the status of the reseller authorization from the deal record in HubSpot or in the Fours Console. **Q: Will the reseller authorization show up in the Fours Console too?** Yes. Any reseller authorization created from HubSpot is also visible in the Fours Console under your offers list. --- Source: https://doc.fours.com/hubspot-app/hubspot-app-cosell/ # Create Co-Sell Submit a co-sell referral to AWS, Azure, GCP, or a Fours partner directly from a HubSpot deal using the Fours App. --- ## Overview A co-sell referral is how you formally ask AWS, Azure, or GCP to work with you on a deal. When you submit a referral, the cloud provider's sales team can see the opportunity and engage to help you close it — for example, by introducing you to the right contacts, validating the opportunity, or contributing resources. In plain terms, you're sharing a deal with your cloud partner so they can help you win it. The same button also shares a deal with a **Fours partner** — a partner connected to you through [Partner Management](/prm/) — so a referral can go to a channel partner rather than a cloud. After adding the Fours App to your HubSpot Console, you can create all of these straight from a deal. :::info Submitting a co-sell referral does not send anything to your customer. It only shares the deal details with the cloud provider's partner team — your customer will not know a referral was submitted. ::: For more details, see [Co-Sell](/cosell/). ## Prerequisites The Fours App must be set up in HubSpot and the Fours app card must be visible on your deal pages. If you haven't done that yet, see [Set up the Fours App in HubSpot](/hubspot-app/hubspot-app-configuration/). ## Create a Co-Sell 1. Navigate to the deal's detail page and click the **"Suger"** tab at the top of the page. > Suger tab on a HubSpot deal detail page 2. Locate and click the **"Co-Sell"** button. > Co-Sell button in the Suger panel 3. Choose the destination you want to submit the referral to. There are up to four: **AWS**, **AZURE**, **GCP**, and **Partner** — a partner connected to you through Fours. > Cloud partner selection for AWS Azure or GCP The button adapts to what your organization has connected: - **More than one destination** — the button reads **Co-Sell** and opens a dropdown listing each one. - **Exactly one destination** — there is no dropdown. The single entry renders as a plain **Co-Sell** button that opens that destination's form directly. - **No destinations** — the button does not appear at all. :::info A destination only appears if it is configured: AWS needs an AWS integration, Azure needs co-sell enabled on the Azure integration, GCP needs the GCP co-sell service, and **Partner** appears only when your organization has connected Fours partners. ::: If your AWS connection still uses the legacy AWS S3 API, choosing **AWS** opens an **AWS S3 API Deprecated** notice instead of the referral form: *"The AWS S3 API is no longer supported. Please contact your administrator to upgrade to the new AWS ACE API."* Ask your administrator to upgrade to the AWS ACE API — the referral form is not available until they do. 4. Complete the required fields in the form. Note that the required fields may vary depending on which cloud partner you selected. > Co-Sell referral form with required fields :::tip If field mapping has been configured, the form will be prefilled with corresponding fields from the HubSpot deal, making the process faster and easier. Review the pre-filled values for accuracy before submitting. ::: 5. Once all necessary information is filled in, submit the form to create the Co-Sell. > Submitting the completed Co-Sell form 6. You are all set! ## AWS: contacts on the referral form The AWS ACE referral form's **Contact details** accordion holds one customer contact and two partner contacts, each under its own labels so it is clear who is who: | On the form | Who goes here | | --- | --- | | **Customer name**, **Customer title** and **Customer contact details** | The person at the customer this opportunity is with | | **Partner Opportunity Owner**, with its **Contact details** | The person on your side who owns the opportunity | | **Partner Account Manager**, with its **Contact details** | An optional second person on your side | Three behaviours worth knowing: - **The customer contact comes from one deal contact.** On a new referral, your co-sell field mapping fills the customer fields from one of the deal's contacts, picked so that a reseller's contact is not sent as the customer's. [Which deal contact becomes the customer contact](/integrations/hubspot/#which-deal-contact-becomes-the-customer-contact) explains which contact is used and why the fields can come up empty. Editing or re-submitting a referral keeps the contact it was saved with. The Azure and GCP forms pick the customer contact the same way. - **Blank partner contacts are dropped.** If you leave a partner contact section empty, it is not sent to AWS — you do not have to fill in the account manager just to submit. - **Partner contacts are read-only when editing.** Once a referral exists, you can edit the rest of it, but the partner contacts are fixed. On the referral detail, contacts are presented as two separate cards — **Cloud Contacts (AWS)** for the people AWS has assigned, and **ISV Contacts** for yours — so it is clear at a glance which side owns which name. ## Azure: solution area and play The Azure referral form has a **Solution Area/Play** section. Pick the solution area first, then the play underneath it; the second dropdown's placeholder is **Conversation**, and in field mapping the same field is labelled **Solution Play/Conversation**. The solution areas are Microsoft's FY27 set: | Solution area | | --- | | AI Business Solutions | | Cloud and AI Platforms | | Microsoft Services | | Security | | Windows and Devices | :::info Referrals saved before the FY27 change keep whatever they were submitted with. Those older values render as the saved value followed by a `(legacy)` suffix, so you can tell at a glance that the referral predates the current list. Nothing is rewritten for you; pick a current area and play the next time you edit the referral. ::: ## Azure: company lookup and team members **The Microsoft company lookup runs on its own.** When the Azure form opens with a valid customer address, Fours searches Microsoft for the matching company automatically — you no longer need to click **Search**. If the address is incomplete, fix it and use the **Search** button as before. **Adding team members.** The Azure form's **Add Team Member** modal takes four fields: **First Name**, **Last Name**, **Email**, and **Phone Number**. ## Share a deal with a Fours partner Beyond the three clouds, you can share a deal with a partner connected to you through Fours — the same partnership network you manage in [Partner Management](/prm/). It is a fourth destination on the **Co-Sell** button, not a separate tab or button. :::info The **Partner** entry appears only if your organization has connected Fours partners. When it is the only destination available, it renders as a single **Co-Sell** button with no dropdown. ::: ### Step 1 — pick the partner Choosing **Partner** opens the **Share Co-Sell with Partner** panel. It explains what is about to happen: *"Choose a partner connected via Suger. The selected partner will receive an inbound copy of this co-sell."* 1. Start typing in the **Partner** field. Its placeholder is *"Search by name or domain"*, so either works. 2. If there are more matches than the list shows, a hint reads *"+{n} more — keep typing to narrow the list."* Keep typing until your partner appears. 3. Select the partner and click **Continue**. ### Step 2 — complete the form The second step is the co-sell form itself, organized into accordions: | Accordion | What you enter | | --- | --- | | **Customer & Opportunity** | The customer company name, website, industry, and country, plus the opportunity type | | **Deal Details** | Deal name, target close date, the customer's business problem, delivery model, and the deal value | | **Revenue Share** | Commission type, revenue share model, payment trigger, and clawback window. **Shown only when you are the seller** | | **Partner Collaboration** | What you need from the partner on this deal | | **Team** | Your people on the deal. Use **Add Team Member** to add a row and **Remove** to drop one | The footer has two buttons: **Back** to return to the partner picker, and **Share Co-Sell** to submit. Two things about this form catch people out: - **The deal role is not editable.** Whether you are the **Seller** or the **Referrer** on this co-sell is derived from your partnership relationship type with that partner — you cannot change it on the form. It also drives what you see: the **Revenue Share** accordion only appears for the Seller, and for the Referrer the deal-value field is labelled **Estimated Deal Value** rather than **Deal Value**. - **The customer business problem has a minimum length.** It must be at least 20 characters, so a one-word answer will not submit. Option lists used on this form: | Field | Options | | --- | --- | | **Revenue Share Model** | `% of Final Transaction`, `Fixed Amount`, `To Be Defined` | | **Deal value visibility** | `Show deal value`, `Hide deal value` | ### After you share Partner co-sells appear in the same **Co-Sell** table as your cloud referrals, with **Partner** identifying the destination. Opening one shows the **Partner Co-Sell** modal with the details as shared: **Overview**, **Customer**, **Deal**, **Revenue Share**, and **Team**. The modal is no longer read-only. It now carries the same three surfaces the Fours Console has: #### Activity An **Activity** tab holds the conversation on the co-sell — messages grouped into threads, each with its author. Posting is scoped: a message can be **internal** to your side, or visible to **everyone** on the co-sell. Use it instead of a side email thread, so the discussion stays attached to the deal both parties are looking at. #### Add Partner **A co-sell is created with exactly one partner.** The create API takes a single partner by contract, so Partner 1 is fixed when you share the deal — every additional partner joins afterwards, through the **Add Partner** dialog on this modal. Revenue-share terms for the partner you add prefill from that partner's own commission setting: their custom plan when they have one, your standard defaults otherwise. #### Commission A **Commission** section on the modal pre-populates from the HubSpot deal rather than asking you to retype figures that already exist on the record. ## Track referrals on the Co-Sell tab The **Co-Sell** tab lists every referral raised from this deal, cloud and partner alike: | Column | What it shows | | --- | --- | | **Name** | The opportunity name. Click it to open the referral's detail modal | | **ID** | The referral identifier | | **Partner** | Where it was submitted — AWS, Azure, GCP, or a Fours partner | | **Direction** | Whether the referral is outbound (you shared it) or inbound (it was shared with you) | | **Status** | Where the referral stands with that partner | | **Create Date** | When the referral was created | | **Last Activity Date** | When it last changed | **Failed updates are flagged on the row.** If an AWS referral is in **UPDATE_FAILED**, an error badge appears next to its name. Hover it and the tooltip shows the raw failure message returned by AWS, which is usually enough to tell you which field to correct before resubmitting. ## Engagement score on the Insights tab The deal's **Insights** tab — and the **Co-sell Insights** card on company records — groups the customer's co-sell signals by cloud, in blocks headed **AWS Co-sell Signals**, **Azure Co-sell Signals** and **GCP Co-sell Signals**. Each block leads with **Suger Predicted Engagement Score**. It is Fours' prediction for the customer's company, not a score a cloud gave a specific referral: - **On a deal, it is still the company's score.** The tab shows the score for the deal's associated company and no longer swaps in the engagement score from the deal's AWS referral. - **No score, no row.** When Fours has no score for the customer on a cloud, the row is left out rather than shown empty. How the score is worked out, and how it differs from a partner's own score on a referral, is covered in [Engagement Score](/cosell/co-sell-insights/#engagement-score). Fours can also write it into a HubSpot property through CRM Enrichment — see [What intelligence signals can Fours write into HubSpot?](/hubspot-app/hubspot-app-faq/#what-intelligence-signals-can-fours-write-into-hubspot) ## What happens next After you submit the referral: - Fours creates the referral and links it to the HubSpot deal. - The referral is sent to the cloud partner's system — for example, AWS Partner Central (ACE), Azure Partner Center, or Google Cloud Partner Network. If you shared it with a Fours partner instead, that partner receives an inbound copy of the co-sell. - The cloud partner reviews the referral and may accept, reject, or request more information. - Any future updates Fours syncs from your HubSpot deal are automatically reflected on the referral — you do not need to manually push updates to the cloud partner. - The referral is also visible in the Fours Console under your referrals list. ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | No Suger tab visible on the deal page | The Fours app card has not been added to the deal layout | Set up the Fours App in HubSpot to add the app card | | No Co-Sell button visible inside the Suger panel | The HubSpot integration connection has been disrupted | Go to Fours Console → Settings → Integrations → HubSpot and click Verify to re-verify the connection | | Only one or two destinations appear in the selector | Your Fours account may not have co-sell configured for all clouds | Contact your Fours admin to confirm which cloud partners are enabled for co-sell. With exactly one destination there is no dropdown at all — a single **Co-Sell** button is the expected behaviour | | **Partner** is missing from the selector | Your organization has no connected Fours partners | The **Partner** destination only appears once a partnership exists. See [Partner Management](/prm/) | | Choosing **AWS** opens an "AWS S3 API Deprecated" notice | The AWS connection still uses the legacy AWS S3 API | Ask your administrator to upgrade the integration to the AWS ACE API. The referral form is unavailable until then | | Form fields are blank — not pre-filled from the deal | Field mapping has not been configured | Field mapping is an optional admin setup. Contact your admin to configure it | | The customer contact is empty on a new referral, while other fields are pre-filled | The deal has two or more companies and none of its contacts belongs to the primary company, or the deal has no contacts | See [Which deal contact becomes the customer contact](/integrations/hubspot/#which-deal-contact-becomes-the-customer-contact), or type the contact in before you submit | | Referral was submitted but is not visible on the deal | Sync between Fours and HubSpot is delayed | Refresh the page after a few minutes. If it still doesn't appear, confirm the referral was created in the Fours Console | ## Frequently Asked Questions (FAQs) - **Q: What's the difference between a co-sell referral and a private offer?** **A:** A co-sell referral shares your deal with the cloud provider's partner team so they can help you close it. A private offer is a custom-priced contract you send directly to a buyer. They serve different purposes — co-sell is about getting the cloud partner involved in the deal; a private offer is the actual transaction. - **Q: Can I submit a referral to more than one cloud partner for the same deal?** **A:** Yes. You can submit separate co-sell referrals to AWS, Azure, and GCP from the same HubSpot deal — just click **Co-Sell** again and select a different partner. - **Q: Do I need to manually update the referral every time the deal changes in HubSpot?** **A:** No. Fours automatically syncs changes from your HubSpot deal to the referral. If you update mapped fields on the deal, those changes flow through to the cloud partner automatically. - **Q: Will the co-sell referral show up in the Fours Console too?** **A:** Yes. Any referral created from HubSpot is also visible in the Fours Console under your referrals list. --- Source: https://doc.fours.com/hubspot-app/hubspot-app-funding/ # Create Funding Apply for AWS partner funding directly from a HubSpot deal using the Fours App — any of the seven AWS funding programs, from Market Development Funds and Proof of Concept to the Migration Acceleration Program and MPOPP Grow. --- ## Overview Funding is money AWS contributes to the work you do around a deal — a marketing activity, a proof of concept, a migration, or promotional credits for the customer. You apply for it, AWS reviews it, and the approved amount is paid out as cash or as credits. The **Funding** tab on the Fours app card is where those applications live. From it you can submit a new funding application against the deal in front of you, and see every application already raised from that deal with its current status. :::info Funding is the one action on the Fours card that does **not** need a product in Fours. An offer or a resale authorization is built on a product; a funding application is built on the deal and your AWS ACE integration. ::: For the console-side view of the funding lifecycle — what each status means, how approvals and claims progress, and where funding lives outside HubSpot — see [Co-Sell Funding](/cosell/cosell-funding/). ## Availability Funding in HubSpot is **AWS only**, and it requires the **AWS ACE (Partner Central)** integration. - If your Fours organization has no AWS integration, the **New Funding** button does not appear on the card at all. - If your AWS connection still uses the legacy AWS S3 API, the button appears but opens an **AWS S3 API Deprecated** notice instead of the form. Ask your administrator to upgrade to the AWS ACE API. There is no Azure or GCP equivalent of this tab. ## Prerequisites - The Fours App must be set up in HubSpot and the Fours app card must be visible on your deal pages. If you haven't done that yet, see [Configuration](/hubspot-app/hubspot-app-configuration/). - Your Fours organization must have an **AWS ACE (Partner Central)** integration. No product is required. ## Create a funding application You pick the program on the deal, Fours pre-fills the form from the deal, and on submit Fours sends the application to AWS Partner Central and tracks it on the deal's **Funding** tab: ```d2 direction: right deal: "HubSpot deal\n(New Funding)" suger: "Fours" aws: "AWS Partner Central" tab: "Funding tab\non the deal" deal -> suger: "program +\nfunding type" suger -> deal: "form pre-filled from\nthe HubSpot mapping" {style.stroke-dash: 4} deal -> suger: "Submit" suger -> aws: "funding\napplication" aws -> suger: "status and\nexternal ID" {style.stroke-dash: 4} suger -> tab: "status and\ndetails" ``` 1. Open the deal and click the **"Suger"** tab at the top of the page. 2. Click the **"New Funding"** button. The **Create Funding Application** panel opens. 3. Choose a **Program Type** and a **Funding Type**. Both are required before the form appears — until then the panel reads *"Select a program type and funding type to load the funding form prefilled from this deal."* | Program Type | Funding Type | | --- | --- | | **Market Development Funds** | `Cash` or `Credit` | | **Proof of Concept** | `Cash` or `Credit` | | **Migration Acceleration Program** | `Cash` only | | **PIF: SCA GenAI Proof Of Concept Funding** | `Cash` or `Credit` | | **PIF: SCA GenAI Marketing Development Funds** | `Cash` or `Credit` | | **ISV Workload Migration** | `Credit` only | | **MPOPP Grow** | `Credit` only | When a program has only one funding type, Fours selects it for you and the **Funding Type** field is locked. What each program pays for is covered in [Choose a funding program](/cosell/cosell-funding/#choose-a-funding-program). 4. Wait for the pre-fill to finish. As soon as both selections are made, Fours maps your deal onto the funding form and a **"Previewing from deal..."** spinner runs while it does. - If part of the deal could not be mapped cleanly, a **Mapping warnings** alert appears above the form, naming each field and the reason. Check those fields before you submit. A field Fours could not fill at all is simply left for you to complete — no alert is shown for it. - If there is no mapping for this program and funding type, a **Preview unavailable** warning appears and the form opens empty, ready to fill in by hand. - Changing **Program Type** or **Funding Type** clears the pre-filled values and runs the preview again, so values from the previous selection never leak into the new form. HubSpot has its own funding mappings: an admin sets them up in the Fours Console for HubSpot, one per program and funding type, and a Salesforce mapping for the same program does not pre-fill a HubSpot deal. See [Create AWS funding from a HubSpot deal](/cosell/cosell-funding/#create-aws-funding-from-a-hubspot-deal). 5. Complete the form. It is organized into accordions — **Funding Request**, **Opportunity**, **Project Information**, **Cash Request** or **Credit Request**, **Marketplace Offer**, **Wallet** and **Attachment** — and shows only the ones your program uses. The **Migration Acceleration Program** has a layout of its own; see [Migration Acceleration Program](#migration-acceleration-program) below. Every other program asks for **Project Name**, **Business Description**, the partner contact's **First Name**, **Last Name**, **Email Address** and **Job Title**, **Planned Start Date**, **Planned End Date**, **AWS Account ID**, **Country Activity is Executed** and — for a US activity — **State(s) Activity is Executed**, and takes an **Attachment** for supporting documents. On top of that: | Program | Linked AWS opportunity | Wallet | Also asks for | | --- | --- | --- | --- | | **Market Development Funds** | — | Required | The WWPS consent checkbox | | **Proof of Concept** | Yes — required | — | **Annual Recurring Revenue (ARR)**, optional **AWS Pricing Calculator URL(s)**, optional **Customer Also Considering** | | **PIF: SCA GenAI Proof Of Concept Funding** | Yes | — | **Annual Recurring Revenue (ARR)**, optional **AWS Pricing Calculator URL(s)**, the WWPS consent checkbox | | **PIF: SCA GenAI Marketing Development Funds** | — | Required | The WWPS consent checkbox | | **ISV Workload Migration** | Yes | — | **Workload Source Being Deprecated**, **Annual Recurring Revenue (ARR)** and its **Annual Recurring Revenue Calculation Method** | | **MPOPP Grow** | Yes | Optional | **Annual Recurring Revenue (ARR)**, **Total Contract Value**, optional **AWS Pricing Calculator URL(s)**, **Customer Also Considering**, **Workload Name**, **Project Type**, *Is this a new service being deployed?*, optional **Other Notes**, the WWPS consent checkbox, and the **Marketplace Offer** accordion | - **Linked AWS Opportunity ID** is pre-filled with the deal's own AWS opportunity when it has one. The list offers only opportunities at a stage the program accepts: | Program | Opportunity stages offered | | --- | --- | | **Proof of Concept**, **PIF: SCA GenAI Proof Of Concept Funding** | Technical Validation, Business Validation, Committed, Launched | | **ISV Workload Migration** | Launched | | **MPOPP Grow** | Business Validation, Committed, Launched | | **Migration Acceleration Program** | Any stage | - **Wallet** lists your organization's active wallets for that program — Market Development Funds, PIF: SCA GenAI Marketing Development Funds and MPOPP Grow each draw on wallets of their own. - **Dates.** **Planned Start Date** must be at least 14 days from today and in the current year. **Planned End Date** must be in the current year, after the start date, and before the 16 December to 1 January blackout. - **Low ARR.** On **Proof of Concept** and **PIF: SCA GenAI Proof Of Concept Funding**, an ARR below 10,000 needs an **AWS Pricing Calculator URL(s)** entry or an attachment of type **AWS Pricing Calculator**. - **MPOPP Grow's Marketplace Offer.** Once you pick the opportunity, Fours fills **AWS Marketplace Offer - optional** with the Marketplace offer linked to that opportunity, and **AWS Marketplace Product - optional** from that offer. Leave both empty if the opportunity has no linked offer. If the offer list cannot load, the field reads *"Failed to load offers — reopen the panel to retry"*. - **Attachment.** Each application can carry one attachment. Pick its **Attachment Type**, then choose the file under **Attachment File** from your organization's [Files](/settings/files/), or click **Upload new File** to add one. Every program except **ISV Workload Migration** offers the same 19 types; ISV Workload Migration offers 7 of them. Both lists are in [Attach supporting documents](/cosell/cosell-funding/#attach-supporting-documents). 6. Fill in the **Cash Request** or **Credit Request** accordion — see [Cash requests](#cash-requests) and [Credit requests](#credit-requests) below. 7. Click **Submit**. Fours confirms with **"Funding application submitted!"**, returns you to the **Funding** tab, and the new application appears in the table. If it does not show up immediately, refresh the card. If anything on the form is still invalid, the panel says *"Please check and fix the form errors"* instead. ### Cash requests Every cash request asks for your **Payee Central Account Profile ID** — 10 to 13 letters or digits, from your company's Amazon Payee Central profile. It replaces the **Invoice Entity Name**, **Invoice Remit Country** and **Invoice Remit Address** fields, which are gone from the form, and a cash request cannot be submitted without it. The rest of the accordion depends on the program: | Program | Cash Request | Cash Claims | | --- | --- | --- | | **Market Development Funds** | **Currency** and the profile ID | One or more claims, each with **MDF Cash Activity Type**, **Start Date**, **End Date**, **Total Cost of MDF Activity**, **Requested MDF Cash Funding** and **Number of Projected Leads** | | **Proof of Concept** | **Currency**, the profile ID, **Total Cost of Activity**, and optional **Partner Contribution** and **Customer Contribution** | Exactly one claim, with a **Start Date** and **End Date** | | **PIF: SCA GenAI Proof Of Concept Funding** | As Proof of Concept, plus **Requested Amount** — the amount you ask AWS for | One or more claims with a **Start Date** and **End Date**, plus optional **Expected Revenue Ramp (USD)** and **Percentage Completion (%)** | | **PIF: SCA GenAI Marketing Development Funds** | As PIF: SCA GenAI Proof Of Concept Funding | One or more claims with a **Start Date** and **End Date** | Where a program takes several claims, **Add Cash Claim** adds one, up to 10, and **Remove Claim** drops one. Claim dates must be in the current year and inside the planned start and end dates. On a Market Development Funds claim, **MDF Funding %** is calculated from the amounts you enter and is capped at 50 — you cannot request more than half the activity cost. ### Credit requests | Program | Credit Request | | --- | --- | | **Market Development Funds** | **Currency**, **Value Per Code**, **Number of Codes**, **Requested Amount** (calculated for you), **MDF Credit Activity Type** | | **Proof of Concept** | **Currency**, **Total Cost of Project** | | **PIF: SCA GenAI** programs and **MPOPP Grow** | **Currency**, **Number of Codes** (at least 1), **Value Per Code (USD)** | | **ISV Workload Migration** | **Request Credit Amount**, in whole numbers | ### Migration Acceleration Program A Migration Acceleration Program (MAP) request is always cash, and its form is laid out differently: | Accordion | What you enter | | --- | --- | | **Migration Details** | **Migration Phase** — **Assess** or **Mobilize** — and **Annual Recurring Revenue (ARR)**, which must be at least 100,000. On **Mobilize**, a checkbox confirms that over 75% of the servers being migrated are VMs hosted on VMware. | | **Opportunity** | **Linked AWS Opportunity ID**, from opportunities at any stage | | **Project Details** | **Project Name** (up to 300 characters), **Business Description** (up to 5,000), **Project Start Date (UTC)** — at least 14 days from today and in the current year — and **Project End Date (UTC)**, on or after the start; a 12-digit **AWS Account ID**, **Country** and **States**, optional **AWS Pricing Calculator Estimates**, and the partner contact | | **Cash Request** | **Currency**, **Total Cost of Project**, **Total Amount Requested from AWS** (whole numbers) and **Payee Central Account Profile ID**. The currency and profile ID must match your company's Amazon Payee Central account. | | **Attachment** | Supporting documents | For what AWS expects on a MAP request, see [Migration Acceleration Program requests](/cosell/cosell-funding/#migration-acceleration-program-requests). ## Track applications on the Funding tab The **Funding** tab lists every funding application raised from this deal: | Column | What it shows | | --- | --- | | **Name** | The project name from the application. Click it to open the application's details | | **Program** | The AWS program the application was submitted under | | **Status** | Where the application stands, as a tag. If the application has an error, a red exclamation tag sits beside it — hover it to read the message | | **External ID** | The AWS-side identifier for the application | | **Last Update** | When the application last changed | Before you raise your first application, the tab shows **"No funding applications — Create one from this deal with the New Funding button."** ### Open an application's details Click an application's name to open its details. They are read-only: - **A failed application leads with the error.** An *AWS funding application failed* alert at the top gives its error message. - **Overview** — Name, Program, **Suger Status**, **AWS Status** and **Stage**, External ID, Benefit ID, Catalog, Fulfillment Types, and when the application was created and last updated. **Stage** is how far the request has moved through AWS's fund request process — **Business approval**, **Finance approval**, **Pre-approval**, **Cash claim** or **Application completion**, the step names described in [Read the stage](/cosell/cosell-funding/#read-the-stage). It is left out until AWS reports a stage, and a stage Fours does not recognise is shown exactly as AWS sent it. - **Application Details** — the fields this program's application carries, such as the project name, planned dates, country, ARR or migration phase. Fields the application does not use are left out. - **Cash Request** with a **Cash Claims** table, or **Credit Request**. - **Approval** — where the application stands in your organization's funding approval workflow, when one applies: its status, decision date and message. - **Partner Contact**, **Associated Resources** (the AWS opportunity or wallet the application is linked to) and **Attachments**. Once an application is submitted, the **Fours Console** is where you follow it through review, approval, and claims — see [Co-Sell Funding](/cosell/cosell-funding/). The HubSpot card shows the status and the details; the console holds the full lifecycle. ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | No **New Funding** button on the Suger card | Your Fours organization has no AWS integration | Funding is AWS-only. Confirm an AWS integration exists in Fours Console → **Settings** → **Integrations** | | **New Funding** opens an **AWS S3 API Deprecated** notice | The AWS connection still uses the legacy AWS S3 API | Contact your administrator to upgrade to the AWS ACE (Partner Central) API | | The form does not appear after opening the panel | **Program Type** and **Funding Type** have not both been selected | Select both. The form is only built once the program and funding type are known — a program with a single funding type selects it for you | | **Preview unavailable** warning after choosing the program | No HubSpot funding mapping exists for this program and funding type, or the preview could not run | Fill in the form by hand, or ask your admin to add a HubSpot mapping for that program and funding type | | **Mapping warnings** alert appears above the form | Part of the deal could not be mapped cleanly onto the funding application | Check each field named in the alert and correct it by hand before submitting | | Fields are blank — nothing pre-filled from the deal | No HubSpot funding mapping for this program and funding type | Mappings are set per CRM, program and funding type, so a Salesforce mapping does not pre-fill HubSpot. Ask your admin to configure one — see [Create AWS funding from a HubSpot deal](/cosell/cosell-funding/#create-aws-funding-from-a-hubspot-deal) | | The opportunity you want is not in **Linked AWS Opportunity ID** | Its stage is not one the program accepts | The list shows only opportunities at an eligible stage — see the stage table in step 5 | | The **Wallet** list is empty | Your organization has no active wallet for this program | See [Monitor wallets and purchase orders](/cosell/cosell-funding/#monitor-wallets-and-purchase-orders) | | A red exclamation tag sits next to an application's status | The application failed or carries an error | Hover the tag to read the message, or click the application's name to open its details | | A submitted application is not in the Funding tab | Sync between Fours and HubSpot is delayed | Refresh the card after a few minutes, then confirm the application exists in the Fours Console | ## Frequently Asked Questions ### Do I need a product in Fours to apply for funding? No. Funding is the exception on this card — offers and resale authorizations are built on a product, but a funding application is built on the deal plus your AWS ACE integration. You can apply for funding even if you have no products set up. ### Can I apply for funding on an Azure or GCP deal? No. Funding on the Fours card is AWS-only. The **New Funding** button does not appear unless your organization has an AWS integration. ### What is the difference between Cash and Credit? A cash request is tied to your company's Amazon Payee Central account — AWS takes the invoicing details from that profile — so every cash program asks for its **Payee Central Account Profile ID** instead of invoice fields, and Market Development Funds cash claims also carry projected leads. A credit request asks for promotional credits instead: Market Development Funds, both PIF: SCA GenAI programs and MPOPP Grow ask for a number of codes and a value per code, ISV Workload Migration asks for a credit amount, and Proof of Concept for the total cost of the project. Not every program offers both — the Migration Acceleration Program is cash-only, and ISV Workload Migration and MPOPP Grow are credit-only. ### Why is the MDF Funding % capped at 50? AWS funds up to half the cost of an MDF activity. The field is calculated from the activity cost and the amount you request, and it will not go above 50 — if it does, lower the requested amount or raise the total activity cost. ### Where do I track the application after submitting? In the Fours Console. The **Funding** tab in HubSpot shows the current status and the AWS external ID, and clicking an application's name opens its details, including its stage and any error; the full review, approval, and claim lifecycle lives in the console — see [Co-Sell Funding](/cosell/cosell-funding/). --- Source: https://doc.fours.com/hubspot-app/hubspot-app-faq/ # HubSpot FAQ and Troubleshooting Answers to common questions and fixes for issues you may hit while using the Fours App in HubSpot. --- ## Overview This page covers frequently asked questions and troubleshooting for the Fours App in HubSpot. If you're setting up the app for the first time, start with [Configuration](/hubspot-app/hubspot-app-configuration/) and, before that, [Integration with HubSpot](/integrations/hubspot). ## Frequently asked questions ### Do I need to complete the HubSpot integration before using the Fours App? Yes. The integration must be completed and verified in Fours Console before the Fours App card will appear in HubSpot. See [Integration with HubSpot](/integrations/hubspot) to set this up first. ### What HubSpot permissions does the Fours integration need? Fours requires a dedicated integration user with view and edit access on CRM contacts, companies, and deals, plus permission to edit property settings and access the App Marketplace. The app requests these scopes: | Scope | Required or optional | | --- | --- | | `oauth` | Required | | `crm.objects.companies.read`, `crm.objects.companies.write` | Required | | `crm.objects.contacts.read`, `crm.objects.contacts.write` | Required | | `crm.objects.deals.read`, `crm.objects.deals.write` | Required | | `crm.objects.owners.read` | Required | | `crm.schemas.companies.read` | Required | | `crm.schemas.contacts.read` | Required | | `crm.schemas.deals.read` | Required | | `automation` | Optional | | `crm.lists.read`, `crm.lists.write` | Optional | | `crm.objects.custom.read`, `crm.objects.custom.write` | Optional | | `crm.schemas.custom.read` | Optional | | `crm.objects.users.read` | Optional | Note that only the **read** variants of the three schema scopes are requested — Fours reads your company, contact, and deal property definitions but does not change them. ### Can I add the Fours app card to more than one deal view? Yes. The app card is added per view — repeat the customization steps for each view your team uses. See [Configuration](/hubspot-app/hubspot-app-configuration/). ### What is field mapping and do I need it? Field mapping is an optional configuration that automatically pre-fills the offer, co-sell, and funding forms with data from the HubSpot deal — like company name, deal value, or close date. You can create offers, referrals, and funding applications without it, but you'll need to fill in all fields manually. Contact your admin to set it up. ### Can I submit co-sell referrals to AWS, Azure, and GCP from the same deal? Yes. Click **Co-Sell** in the Suger panel for each cloud partner separately. Each referral is independent and tracks its own status. ### Can I share a deal with one of our partners instead of a cloud? Yes. **Partner** is a fourth destination on the same **Co-Sell** button, and it opens the **Share Co-Sell with Partner** panel. It only appears if your organization has partners connected through Fours — see [Partner Management](/prm/) and [Create Co-Sell](/hubspot-app/hubspot-app-cosell/). ### Why can't I change the deal role when sharing with a partner? The role — Seller or Referrer — is derived from your partnership relationship type with that partner, so it is not editable on the form. It also controls what you see: the **Revenue Share** section appears only for the Seller, and the Referrer sees **Estimated Deal Value** instead of **Deal Value**. ### Do I need a product in Fours to apply for funding? No. Funding is the exception on the Fours card — offers and resale authorizations need a product, but a funding application only needs the deal and an AWS ACE (Partner Central) integration. See [Create Funding](/hubspot-app/hubspot-app-funding/). ### Why don't I see the New Funding button? Funding is AWS-only. If your organization has no AWS integration the button is not rendered at all, and if the AWS connection still uses the legacy AWS S3 API the button opens an **AWS S3 API Deprecated** notice instead of the funding form. Ask your administrator to upgrade to the AWS ACE API. ### Where do I track a funding application after submitting it? The **Funding** tab on the deal shows the current status and the AWS external ID; click an application's name to open its details, including its stage and any error. The full review, approval, and claim lifecycle lives in the Fours Console — see [Co-Sell Funding](/cosell/cosell-funding/). ### How does Fours sync changes from HubSpot to my co-sell referrals? Fours automatically syncs updates from your HubSpot deals to linked referrals. If you update mapped fields on a deal, those changes flow through to the cloud partner without any manual action required. ### Can I enrich HubSpot deal and company records with marketplace intelligence data? Yes. Fours' CRM Enrichment feature can automatically populate HubSpot properties with engagement scores and marketplace metrics from AWS, Azure, and GCP. Enrichment syncs every 2 hours. This is configured in Fours Console → **Settings** → **Integrations** → **HubSpot** → **Enrichment** tab. See [Integration with HubSpot](/integrations/hubspot) for setup details. ### What intelligence signals can Fours write into HubSpot? Fours can sync the following signals into custom HubSpot properties: - **AWS** — Engagement Score, Marketplace Count, Marketplace Review Count, Marketplace Purchase Count - **Azure** — Engagement Score, Event Score, Usage Score, Marketplace Count, Marketplace Review Count, Marketplace Purchase Count - **GCP** — Engagement Score, Marketplace Count, Marketplace Review Count, Marketplace Purchase Count Each cloud's **Engagement Score** is the company-level score that the deal's **Insights** tab and the **Co-sell Insights** card show as **Suger Predicted Engagement Score** — Fours' prediction for the customer, not a score a cloud gave a specific referral. See [Engagement score on the Insights tab](/hubspot-app/hubspot-app-cosell/#engagement-score-on-the-insights-tab). ### How do I stop the integration without deleting everything? To temporarily pause enrichment, set **Update records that already have enrichment data** to **Never** in the enrichment configuration — Fours will stop refreshing existing records but won't remove anything. To fully remove the integration, click the 🗑️ button on the HubSpot card in Fours Console → **Settings** → **Integrations**. You can also uninstall the Suger App directly from your HubSpot account settings. ## Troubleshooting common issues | Issue | Possible cause | Resolution | | --- | --- | --- | | Suger does not appear in HubSpot's Apps list when customizing a deal view | The HubSpot integration has not been completed or verified | Complete the integration first. The status in Fours Console must show **Verified** | | Fours app card was added to the deal view but is not visible on deal records | The record customization was not saved | Go back to **Customize record**, confirm the Suger card is in the layout, and click **Save and exit** | | Fours app card shows an error or blank state | The integration connection has been disrupted | Go to Fours Console → **Settings** → **Integrations** → **HubSpot** and click **Verify** to re-verify the connection | | No **New Offer**, **New Resale**, **New Funding**, or **Co-Sell** button visible in the Suger panel | Integration connection is broken or unverified | Re-verify the integration as above. **New Funding** and **Co-Sell** are also gated on what is connected — **New Funding** needs an AWS integration, and **Co-Sell** only lists destinations your organization has configured | | Offer or referral created in HubSpot is not visible on the deal | Sync between Fours and HubSpot is delayed | Refresh the page after a few minutes. Confirm the record was created successfully in the Fours Console | | Offer URL is not available after creating an offer | The cloud marketplace has not finished processing the offer | Wait 3–5 minutes and refresh the page. The URL appears once the marketplace confirms the offer | | HubSpot form fields are not pre-filling from the deal | Field mapping has not been configured | Field mapping is optional — contact your admin to set it up | | Enrichment data is not appearing on HubSpot records | Custom properties don't exist, or the integration user lacks write access | Confirm custom properties are created in HubSpot and that the integration user has edit access on those properties | | Enrichment sync shows "Active" status but no refresh is happening | **Update records that already have enrichment data** is set to **Never** | Update the setting to **Every N days** or **Immediately** in Fours Console → Enrichment configuration | --- Source: https://doc.fours.com/hubspot-app/hubspot-app-entitlements/ # Entitlements Read a live agreement from the HubSpot deal it belongs to, without opening the Fours Console. --- ## Overview The **Entitlements** tab on the Fours deal card lists the agreements created when a buyer accepted one of your offers. An entitlement is the live contract: the offer is what you sent, the entitlement is what the buyer is actually running on. ## What the card shows Selecting an entitlement opens its info panel. Which rows appear depends on the marketplace and the contract — a field with nothing behind it is omitted rather than shown empty. | Field | What it is | | ----- | ---------- | | **ID** / **External ID** | Fours' identifier, and the marketplace's own. | | **Status** | Where the agreement stands. | | **Type** | The entitlement type. | | **Offer Delivery Method** | How the offer reached the buyer. | | **Partner** | The marketplace it came from. | | **Start Time** / **End Time** | The contract window. On a GCP entitlement both show a Pacific date and time, with PST or PDT, as GCP's Producer Portal does. | | **Creation Time** / **Last Update Time** | When Fours created and last synced the record. | | **Term Length** | The contract term. | | **Currency** | The contract currency. | | **Commit Amount** | The committed amount. | | **Gross Amount** | The gross contract amount. | | **Invoiced Amount** | What has been invoiced so far. | | **Billing Cycle** | How often the buyer is billed. | | **Auto Renew** | **Yes** while the agreement is set to renew automatically. When auto-renewal is off, the row is left out. | | **Renewal Disabled Reason** | Why the agreement will not renew, when it will not. | | **Initial Agreement ID** | The first agreement in a renewal chain. | | **Seller Notes** | Notes carried on the agreement. | Fours also keeps an active GCP entitlement's **End Time** aligned with the end of its offer's term, so an End Time that was recorded a day late is corrected on a later sync. See [GCP: dates in Pacific time](/hubspot-app/hubspot-app-offer/#gcp-dates-in-pacific-time). ## Downloads Two buttons appear at the bottom of the panel when there is something to fetch: | Button | What it gives you | | ------ | ----------------- | | **EULA** | The end-user licence agreement for the entitlement. | | **Invoice** | The invoice for the entitlement. | Both open in a new tab. ## AWS renewal details An AWS agreement carrying [pre-authorized auto-renewal](/aws-marketplace/pre-authorized-auto-renewal/) terms grows a **Renewal** section, read-only, with the terms the buyer accepted: | Field | What it tells you | | ----- | ----------------- | | **Renewal status** | Whether the agreement is set to renew. | | **Renewal Pricing** | The uplift shape that was agreed. | | **Price uplift range** | The pre-negotiated minimum and maximum, on a range term. | | **Default uplift percentage** | Where inside the range the uplift sits if nobody adjusts it. | | **Uplift status** | Whether the uplift is still open or locked in: *Pending uplift*, *Finalized YYYY-MM-DD*, or *Finalized*. See [Adjust the renewal uplift](#adjust-the-renewal-uplift). | | **Renewal count** | How many renewals are authorized. | | **Lockout date** | The date after which opting out is no longer possible — the renewal decision deadline set on the offer. | | **Adjustment deadline** | The date after which the uplift can no longer be changed. | | **Next renewal date** | When the next term begins. | | **Renewal error** | Shown only when a renewal operation failed, with the message. | When the offer carried one, a **Renewal payment schedule** follows: the contract duration, the number of installments, and the schedule itself. **Renewal history** shows the chain of agreements this one belongs to, naming the previous agreement. If Fours has not yet read a predecessor, it says **Predecessor pending** rather than showing a broken chain — the current agreement always renders even when the chain lookup is unavailable. ### Adjust the renewal uplift On a range term, you choose from the card where inside the pre-negotiated range the next renewal's uplift lands. **Adjust Renewal Uplift** appears in the entitlement's actions menu when all of these hold: - the entitlement is an **ACTIVE** AWS agreement whose renewal term has a price uplift range; - auto-renewal is still on; - there is no pending or scheduled cancellation; - the **adjustment deadline** has not passed; - the uplift has not been finalized yet. The **Adjust Renewal Uplift** dialog opens with the agreed **Uplift range**, the **Default uplift** and the **Adjustment deadline**. What you set depends on whether the offer has a payment schedule: | Offer | What you set | | --- | --- | | **Without a payment schedule** | One **Target uplift percentage** for every dimension, previewed line by line under **Contract dimensions** and **Usage dimensions**. Or turn on **Set an uplift per dimension** to give each line its own **Uplift %** — each starts at the range default. | | **With a payment schedule** | The **Target uplift percentage** applies to the installments, previewed under **Payment schedule preview**. Usage dimensions get their own **Usage uplift percentage**, or per-line values with **Set an uplift per dimension**. Contract dimensions cannot be set one by one, because the schedule prices the committed term. | When a single uplift applies, the dialog also totals the **Current TCV** and the **Renewal TCV** at that **Price uplift**. Every value has to sit inside the range: **Save as draft** and **Publish** stay disabled until it does, and an out-of-range percentage field shows *"Uplift must be between {min}% and {max}%."* The prices are a preview — Fours recalculates them when you submit, and AWS validates them. Rates show up to eight decimal places, with trailing zeros dropped — *1.05*, not *1.05000000*. If AWS has not generated the renewal offer yet, the schedule preview says so; you can still save or publish the uplift. Then choose how to submit it: - **Save as draft** stores the repriced renewal offer as a draft. The buyer is not notified, and reopening the dialog picks the draft up where you left it. - **Publish** asks you to confirm first: *"Publishing releases this renewal offer to the buyer and notifies them immediately. This action is irreversible."* Click **Confirm publish** to go ahead, or **Keep editing** to go back. Publishing finalizes the uplift. Once the publish goes through, **Adjust Renewal Uplift** disappears and **Uplift status** reads *Finalized* with the date. Opting out is separate and stays available until the lockout date. | Uplift status | What it means | | --- | --- | | *Pending uplift* | A range uplift that has not been finalized. You can still adjust it before the adjustment deadline — saving a draft leaves it here. | | *Finalized YYYY-MM-DD* | Locked in on that date: you published it, or AWS finalized it when the adjustment window closed. | | *Finalized* | A fixed-percentage or no-uplift term. There is nothing to adjust. | ```d2 direction: right pending: "Uplift status:\nPending uplift" dialog: "Adjust Renewal Uplift" final: "Uplift status:\nFinalized YYYY-MM-DD" pending -> dialog: "before the\nadjustment deadline" dialog -> pending: "Save as draft\n(buyer not notified)" {style.stroke-dash: 4} dialog -> final: "Publish, then Confirm publish\n(irreversible)" pending -> final: "deadline passes:\nAWS finalizes" ``` ### Opt out of auto-renewal The entitlement's actions menu offers **Opt Out of Auto-Renewal**, which stops the agreement renewing. It is available only **before the lockout date**, whether or not the uplift has been finalized. :::warning Opting out is not reversible from Fours. Restoring the renewal means a new offer. ::: Once the renewal is off — because you opted out, or the agreement is otherwise set to expire — **Renewal status** reads *Auto-renew off*, **Next renewal date** reads N/A, and the **Auto Renew** row is no longer shown. ### Changes take a few minutes AWS propagates renewal changes asynchronously, so the card does not update the moment you confirm. Refresh the deal after a few minutes to see the state AWS has recorded. ## Related - [Private Offers](/hubspot-app/hubspot-app-offer/) - [AWS Pre-Authorized Auto-Renewal](/aws-marketplace/pre-authorized-auto-renewal/) - [Configuration](/hubspot-app/hubspot-app-configuration/) --- Source: https://doc.fours.com/hubspot-app/ # HubSpot App The Fours app for HubSpot ships **two cards**. The main one is a deal card: add it to your deal record layout and a **Suger** tab appears on every deal. The second, **Co-sell Insights**, is a company card and is added separately. Inside the deal card, a rep works from **five tabs** — **Offers**, **Entitlements**, **Co-Sell**, **Funding**, and **Insights** — with up to **four action buttons** across the top: **New Offer**, **New Resale**, **New Funding**, and **Co-Sell**. Which buttons you see depends on what your Fours organization has connected, and field mapping (optional) pre-fills their forms from deal properties. :::info Fours was formerly named Suger. Inside HubSpot, the app — its marketplace listing, the **Suger** deal card and tab, and labels such as **Suger Predicted Engagement Score** — still uses the name Suger until the app is renamed. ::: ## Set up the app, then work a deal 1. **[Configuration](/hubspot-app/hubspot-app-configuration/)** — add the Fours app card to your deal record layouts, add the **Co-sell Insights** card to your company layouts, and confirm the Suger tab renders. Complete the HubSpot integration in Fours Console first; the cards will not appear otherwise. 2. **[Create Offer](/hubspot-app/hubspot-app-offer/)** — build a private offer for the buyer on the deal: negotiated pricing, terms, and an expiry date, based on a product that already exists in Fours. The **New Offer** button also covers amendment offers and reseller offers. 3. **[Create CPPO](/hubspot-app/hubspot-app-cppo/)** — use the **New Resale** button instead of a private offer when the deal is with a reseller. You set the wholesale price — or, on Azure, grant a standing resale authorization by customer market — and the reseller creates the final offer to the end customer. 4. **[Create Co-Sell](/hubspot-app/hubspot-app-cosell/)** — share the deal with AWS, Azure, or GCP as a referral, or with a **Fours partner** through [Partner Management](/prm/). Each destination is submitted separately and tracks its own status, and nothing is sent to your customer. 5. **[Create Funding](/hubspot-app/hubspot-app-funding/)** — apply for AWS funding against the deal under any of the seven AWS funding programs, cash or credit. AWS only, and the one action here that needs no product in Fours. ## The Co-sell Insights company card The second card, **Co-sell Insights**, is registered on the **companies** object, not on deals. Adding the Fours deal card does not add it — go to a company record, customize the record layout, and add **Co-sell Insights** the same way. The configuration page above covers both cards. Like the deal's **Insights** tab, the card shows the customer's co-sell signals per cloud, led by the **Suger Predicted Engagement Score** — see [Engagement score on the Insights tab](/hubspot-app/hubspot-app-cosell/#engagement-score-on-the-insights-tab). ## When something does not look right - **[HubSpot FAQ and Troubleshooting](/hubspot-app/hubspot-app-faq/)** — the consolidated answers for the app: required HubSpot scopes, what field mapping does, why the card may not appear, and how changes flow back to co-sell records. ## Scope and limits :::info The HubSpot integration must be completed in Fours Console before any of this works, and you need HubSpot Admin access to customize deal record layouts. See [Integration with HubSpot](/integrations/hubspot/). Each card is added per view, not once per portal — repeat the steps for every deal view your team uses, and again on the company layouts for **Co-sell Insights**. Products must already exist in Fours before you can create an offer or a resale authorization against them. **Funding is the exception** — it needs an AWS ACE (Partner Central) integration rather than a product. Field mapping is optional: without it, every field on the offer, referral, and funding forms is filled in by hand. Working from Salesforce instead? That integration is a managed package with its own objects, permissions, and reports — see [Salesforce App](/salesforce-app/). ::: ## FAQ ### Does our integration with ACE have auto updates when deals are closed/lost or when the date changes to a new close date? Yes. Once an opportunity is submitted through Fours, depending on how your mapping is set up, you can expect any future update on your HubSpot deal to flow to Fours. ### Regarding the HubSpot automation, do I have to refresh Fours sync with ACE so those changes flow through? There is no need to. On a schedule — outbound CRM-to-partner sync runs about every 6 hours; see [Referral Syncing](/cosell/cosell-syncing/) for the current intervals. We collect the data and update the ACE records based on how things are mapped. So, if you made any changes to a deal on HubSpot, you should see an update on ACE in the coming hours. ### I noticed the Buyers do not have any Contacts. When we do the mapping, will every buyer record always have a full email address (i.e., a contact) sent to HubSpot? Yes, buyers don't have a contact associated with them by default. With Fours, future Buyers will because that's something that a feature Fours offers that AWS doesn't. However, that will only be the case for new buyers after the integration. ### I understand that Fours can present a 'propensity to buy' metric. Can we build this into the data integrated into HubSpot? Yes, we support that. It's part of the Co-Sell Implementation. When you submit one of your HubSpot deals to AWS, Fours will collect the Engagement Score for that customer and send it back to HubSpot. The only thing that's needed is for you to provide the field where you want to store that information. --- Source: https://doc.fours.com/chrome-extension/quick-guide/ # Quick Guide Install the Fours Chrome Extension, sign in, and start working with Fours on the pages you already visit every day. --- ## What is the Fours Chrome Extension The Fours Chrome Extension opens Fours inside Chrome's side panel, so you can work with Fours without leaving the page you are on. It is built for people who spend their day moving between cloud marketplaces, a CRM, and the Fours Console — for example: - A partner or co-sell manager sending a referral from a Salesforce opportunity. - An account executive reviewing an AWS, Azure, or Google Cloud offer before a customer call. - A revenue ops lead reconciling a HubSpot deal with a marketplace agreement. - A marketplace operator checking an offer, entitlement, or co-sell referral during triage. Instead of opening multiple Fours tabs, you ask Fours from the side panel — and the answer is already tied to the page in front of you. ## Install the Extension 1. Open the Chrome Web Store listing: [Suger on the Chrome Web Store](https://chromewebstore.google.com/detail/suger/fbbjholgakkpjepancedjddbbociciio). 2. Click **Add to Chrome**, then confirm the installation. > ![Install Suger from the Chrome Web Store](images/install.png) 3. Open the Chrome extensions menu in the toolbar and pin **Suger** so the icon stays visible. > ![Pin the Suger extension in the Chrome toolbar](images/pin.png) 4. Click the Suger icon to open the side panel and sign in with your Fours account. The extension uses the same account as the Fours web console. If you are already signed in there, the side panel picks up your session with no extra steps. ## Pick the Right Organization If your Fours account belongs to more than one organization, use the organization switcher (**settings icon at top right -> organization**) in the side panel to choose which one is active. Before starting any workflow, confirm the active organization matches the environment you intend to work in. This matters most when you manage multiple tenants, business units, or customer environments. ## Get to Know the Side Panel The side panel is the workspace for everything you do with the extension. From the top header you can open and close it, switch conversations, view notifications, and adjust settings. The input area at the bottom is where you ask questions, run skills, and start recordings. > ![Suger side panel with annotations](images/side-panel.png) Key places to know: - **Suger icon in the toolbar** — click to open or close the side panel on any tab. - **Organization and environment label** — confirms which Fours workspace you are connected to. - **Notification, history, and settings icons** — in the side panel header. - **New conversation** — starts a fresh chat when you switch context. - **Edit conversation title** — so you can find past conversations later. - **Permission selector** — choose how much autonomy Fours has for the next request (for example, **Ask before acting** for guided mode). - **Quick recording** — capture the active tab for troubleshooting. ## What You Can Do ### Ask Fours about the page you are on Open the side panel on a page Fours supports and ask a question in plain language. Fours reads the context of the page and answers against your live data. It can also suggest follow-up actions as quick-reply buttons. > ![Asking Suger about the current page](images/ask-current-page.png) Examples of questions that work well: - "Is this offer ready to send to the buyer?" - "Do we already have an entitlement for this customer?" - "What changed on this co-sell referral this week?" - "Show me the last three offers linked to this opportunity." ### Run a skill with a slash command Type `/` in the side panel to open the skill menu. Skills are pre-built flows that take you from a question to a concrete outcome, for example verifying that a marketplace integration is fully configured, diagnosing a failed offer, or drafting a new amendment offer. > ![Slash command menu with Fours skills](images/slash-skills.png) Each skill tells you what it is going to do before it runs and walks you through any decisions along the way. You can stop or skip a step at any time. See [Available Skills](./2.skills.md) for the full catalog. ### Work from Salesforce When you open a Salesforce opportunity, the extension shows a Fours widget beside the record. From the widget you can browse related **Offers**, **Entitlements**, **Referrals**, and **Funding**, and trigger the **Action** menu to start the next step without leaving the page. > ![Suger widget on a Salesforce opportunity](images/salesforce-widget.png) ### Work from HubSpot The same widget is available on HubSpot deals. Open a deal and the side panel shows Fours data linked to it so revenue and partner teams can stay in HubSpot while still working with marketplace records. > ![Suger widget on a HubSpot deal](images/hubspot-widget.png) ### Start a new offer, co-sell, or funding request From the widget's **Action** menu you can kick off the common follow-ups on an opportunity or deal: - **New Offer → Private Offer** — a custom-priced offer sent directly to an end customer through AWS, Azure, or Google Cloud. The buyer receives a link to review and accept it in their marketplace account. Use this when you are selling directly. - **New Offer → Resale Authorization** — a Channel Partner Private Offer (CPPO) that authorizes a reseller to sell your product at a price you set. Use this when selling through a channel partner, and make sure the CRM record is associated with the reseller, not the end customer. - **New Offer → Amendment Offer** — an amendment to an existing offer, for example to change pricing or extend the term after acceptance. This is only available when the buyer already has an active entitlement. - **New Co-Sell** — submit a referral to AWS, Azure, or Google Cloud. You can submit to multiple cloud partners from the same record by repeating the action and selecting a different partner each time. - **New Funding** — create a funding request like an AWS MDF request linked to the account. > ![Action menu with New Offer, New Co-Sell, and New Funding](images/widget-actions.png) The flow opens in a focused popup with the opportunity or deal pre-filled, so you can finish the request without losing your place in the CRM tab. Anything you create is synced back to your CRM and linked to the record automatically. > ![Create Private Offer popup with the Salesforce opportunity pre-filled](images/create-offer-popup.png) :::info How much of the popup is pre-filled depends on your field-mapping configuration. If fields appear blank, contact your Salesforce or HubSpot admin to set up field mapping. ::: :::tip Submitting a co-sell referral only shares deal details with the cloud partner's internal team — it does not contact your customer. ::: :::warning After submitting a private offer, wait 3-5 minutes before copying the offer link. The marketplace needs a few minutes to process the offer, and the URL is not available until the marketplace confirms it. ::: ### Let Fours act for you, with your approval For some workflows, Fours can do more than answer. It can also open a page, fill a form, or prepare a record for you. This is useful when a flow needs several steps across multiple pages. Fours previews each step, you approve it, and it executes — so you stay in control at every point. - Every automated action is shown in the side panel before it runs. - Anything that changes state — creating a record, submitting a form, modifying data — always needs your explicit approval each time, regardless of the autonomy setting. - You can stop or skip any step at any time from the side panel. Use the **permission selector** at the bottom of the side panel to pick how autonomous Fours is on the next request. It does not change what Fours can do — only how often it pauses to ask: | Setting | What it means | | --- | --- | | Ask before acting | Fours previews every step and waits for your approval before executing. Recommended for most users and any time you are trying something new. | | Higher autonomy | Fours moves through steps faster with fewer pauses. Use only when you are already familiar with how a specific workflow runs. | :::tip Always start with **Ask before acting** the first time you run a workflow. Switch to a higher autonomy setting only after you have seen the full workflow run and are confident in each step. ::: Automation runs by default on Fours Console, Salesforce, HubSpot, AWS Console and AWS Marketplace, Azure Portal and Microsoft Partner Center, and Google Cloud Console pages. Fours will not take automated actions on pages outside this trusted list, even if you ask it to — this is a deliberate safety boundary, and the list is fixed. In **Settings → Allowed websites** inside the side panel, you can review and remove sites you previously chose to always allow (which suppresses future approval prompts on that domain). The steps Fours takes stay in the side panel conversation, and you can review past conversations using the **History** icon in the side panel header. ### Record a session to share with support If something goes wrong on a supported page, use the quick recording button in the side panel to capture what happens on the tab. Attach the recording to a support request or an internal review to make the issue reproducible. Recording only starts when you explicitly trigger it and stops when you end it. ### Stay in the loop with notifications The side panel receives updates from Fours as things happen — for example when an offer, entitlement, or co-sell referral changes status, or when a workflow needs your attention. You do not have to refresh a console tab to see them. ## Tips for a Smooth Experience - Pin the Suger icon in the Chrome toolbar so the side panel is always one click away. - Keep the side panel open while you work — it stays attached to the active tab and updates as you navigate. - Before running a skill or approving an action, double-check the active organization at the top of the side panel. - If you start an automated flow, read the step preview before approving each action. You can skip a step or stop at any time. ## Troubleshooting If the extension does not behave as expected: - Confirm you are signed in to Fours and the active organization is correct. - Refresh the current page and reopen the side panel. - Make sure you are on a supported page for the feature you are trying to use. - Update the extension to the latest version from the Chrome Web Store. - If local state seems stale, remove and reinstall the extension. If the issue continues, contact the Fours support team. --- Source: https://doc.fours.com/chrome-extension/skills/ # Available Skills Skills are pre-built flows you run from the side panel to go from a question to a concrete outcome — verifying an integration, diagnosing a failed offer, or generating an offer mapping script. New to the extension? Start with the [Quick Guide](./1.quick-guide.md) to install it and learn the side panel. --- ## Run a Skill Type `/` in the side panel input to open the skill menu, then pick a skill from the list. Each skill tells you what it is going to do before it runs and walks you through any decisions along the way. You can stop or skip a step at any time. Before running a skill, confirm the active organization at the top of the side panel matches the environment you intend to work in. ## Available Skills ### Verify a Marketplace Integration Verify an integration end to end by reading the expected values from the Fours Console and then walking the cloud provider's console step by step with browser tools. | Command | Skill | What it does | | --- | --- | --- | | `/aws-integration-verify` | Verify AWS Marketplace Integration | Reads expected values from the Fours Console UI, then checks the corresponding AWS Console pages. | | `/azure-integration-verify` | Verify Azure Marketplace Integration | Reads expected values from the Fours Console settings page, then walks Azure Portal and Microsoft Partner Center. | | `/gcp-integration-verify` | Verify GCP Marketplace Integration | Reads expected values from the Fours Console settings page, then walks the GCP Console. | ### Diagnose an Offer Creation Error Diagnose a `CREATE_FAILED` private offer using the provider's offer validation rules, and get the specific reason and fix. | Command | Skill | What it does | | --- | --- | --- | | `/aws-offer-diagnosis` | Diagnose AWS Offer Creation Error | Checks pricing dimensions, EULA requirements, buyer account validation, CPPO resale authorization, agreement-based offer rules, and payment installment constraints. | | `/azure-offer-diagnosis` | Diagnose Azure Offer Creation Error | Checks the private offer schema, pricing type, plan fields, billing account, date constraints, EULA rules, and overlap detection. | | `/gcp-offer-diagnosis` | Diagnose GCP Offer Creation Error | Checks pricing metrics, payment schedule constraints, CPPO reseller margin, replacement offer rules, entitlement conflicts, and SKU discount validation. | | `/snowflake-offer-diagnosis` | Diagnose Snowflake Offer Creation Error | Checks target consumer format, pricing plan, terms of service, invoice and access date preferences, and contract type constraints. | ### Generate a Private Offer Mapping Script Generate the JavaScript that builds a private offer from a Salesforce Opportunity, Quote, or custom record. Each skill covers every offer archetype for the provider — branch on `$OfferType` inside the script. | Command | Skill | What it does | | --- | --- | --- | | `/offer-mapping-aws` | Generate AWS Private Offer Mapping Script | Builds a Standard, CPPO, or ABO offer in one script. | | `/offer-mapping-azure` | Generate Azure Private Offer Mapping Script | Builds a Standard or CPPO offer in one script. | | `/offer-mapping-gcp` | Generate GCP Private Offer Mapping Script | Builds a Standard, CPPO, or Replacement offer in one script. | ### Tag an AWS Resource | Command | Skill | What it does | | --- | --- | --- | | `/aws-resource-tag` | Tag AWS Resource for Partner Revenue Measurement | Guides you through tagging AWS resources with the `aws-apn-id` tag for AWS Partner Revenue Measurement (PRM), retrieving the product code from the AWS Partner Central SaaS products page. | --- Source: https://doc.fours.com/chrome-extension/ # Chrome Extension The **Fours Chrome Extension** puts Fours in Chrome's side panel, so you can work with your cloud-marketplace data on the pages you already use — the Fours Console, Salesforce, HubSpot, AWS, Azure, and Google Cloud — without switching tabs. Ask about the page you're on in plain language, run pre-built **skills** with `/` commands, and let Fours prepare records for you with your approval. On a Salesforce opportunity or HubSpot deal, a widget shows the related offers, entitlements, referrals, and funding, and can start a new private offer, resale authorization, co-sell referral, or funding request pre-filled from the record. :::info Fours was formerly named Suger. In Chrome, the extension — its Chrome Web Store listing, toolbar name and icon, and right-click menu items — still uses the name Suger until the extension is renamed. ::: ## Prerequisites - Google Chrome and a Fours account — the extension uses the same session as the Fours Console. ## Get started 1. Install [Suger from the Chrome Web Store](https://chromewebstore.google.com/detail/suger/fbbjholgakkpjepancedjddbbociciio) and pin the icon. 2. Open the side panel, sign in, and confirm the active organization. 3. Ask a question about the current page, or type `/` to run a skill. See the [Quick Guide](/chrome-extension/quick-guide/) for the full walkthrough and [Available Skills](/chrome-extension/skills/) for the skill catalog. ## Access and safety - **Authentication:** your existing Fours Console session — no separate key to manage. - **Automation boundary:** Fours only takes automated actions on a fixed, built-in list of trusted sites (Fours Console, Salesforce, HubSpot, AWS Console and Marketplace, Azure Portal and Microsoft Partner Center, Google Cloud Console); this list can't be extended. Anything that changes state always requires your explicit approval, regardless of the autonomy setting. In the side panel's **Settings → Allowed websites**, you can review and remove sites you previously chose to always allow (which suppresses future approval prompts on that domain). ## Troubleshooting If the extension misbehaves, confirm you're signed in with the correct organization, refresh the page and reopen the side panel, update the extension from the Chrome Web Store, and reinstall if local state seems stale. If the issue continues, contact Fours support. --- Source: https://doc.fours.com/analytics/quick-guide/ # Quick Guide ## Configure Dashboards in Fours Console The **Analytics** page in the Fours console shows the dashboards you pin. Dashboards are created in Fours Analytics, a separate analytics workspace that opens in a new browser tab; you then pin the ones you want to see in the console. ```d2 direction: down create: "Create dashboard\non the Analytics page" workspace: "Fours Analytics\n(new browser tab)" shared: "Public dashboards shared\nwith your organization" choose: "Choose dashboards\n(Manage dashboards)" tabs: "Pinned dashboards,\none tab each on\nthe Analytics page" create -> workspace: "opens" workspace -> choose: "your organization's\ndashboards" shared -> choose: "also listed" choose -> tabs: "Pin" ``` 1. **Open Analytics** Select **Analytics** in the left navigation of the [Fours Console](https://console.suger.io/analytics). You can pin existing dashboards — including public dashboards shared with your organization — or create your own. Until you pin a dashboard, the page shows **No dashboards pinned** with two buttons, **Choose dashboards** and **Create dashboard**. ![Fours Console Analytics page showing a "No Dashboard Configured" empty state with "Choose Existing" and "Create New Dashboard" buttons](images/image13.png) 2. **Create New Dashboards** To create a custom dashboard, click **Create dashboard**. Fours Analytics opens in a new browser tab; [Craft Dashboards](/analytics/craft-dashboards/) walks through creating charts there and assembling them into a dashboard. 3. **Exploring Dashboards** Click **Choose dashboards** to pick the dashboards that appear on your Analytics page — see [Pin a Dashboard in Fours Console](/analytics/craft-dashboards/#pin-a-dashboard-in-fours-console). Each pinned dashboard opens as a tab above the dashboard area; click a tab to switch between dashboards and explore them further. Your pins are your own: they don't change what your teammates see. ![Configured analytics dashboard with widgets for Marketplace Revenue, Private Offers, Total Active Referrals, Top 10 Buyers, Transaction Volume, Revenue by Product, and Region](images/image44.png) ### If a dashboard doesn't load - **Couldn’t load dashboards** means Fours couldn't load your pinned dashboards. Click **Try again**. - **Dashboard unavailable** means the selected dashboard couldn't be opened. If the message reads **We couldn’t open this dashboard. Try loading it again.**, click **Load again**. If it reads **This dashboard is not configured for embedding.**, unpin the dashboard in **Choose dashboards** and pin it again. - If you see **Couldn’t open the analytics workspace. Please try again.**, click **Create dashboard** again. - A pinned dashboard that was deleted in Fours Analytics, or a dashboard another organization shared publicly and has since made private, is removed from your tabs automatically. - A dashboard you leave open keeps working: Fours renews its access in the background while you stay signed in, so you don't need to reload the page. ## Filters Fours provides two types of filters to help you refine the data shown on your dashboards: - **Static Filters**: These filters are typically placed at the top of the dashboard and are authored by the dashboard designer. They are usually required for viewing certain data, ensuring that users can filter by essential parameters like date range, region, or specific partners. - **Interactive Filters**: These filters allow users to click directly on parts of the charts (such as sections of a pie chart or data points on a bar chart) to dynamically apply filters. For example, clicking on "AWS" in a “Revenue by Partners” pie chart applies a dynamic filter of `partner=AWS` to all related charts on the dashboard. ![Dashboard with the static filter bar highlighted at the top, showing "As Of Date" and "Partner" filters above the Product, Offer, Revenue, and Buyer charts](images/image56.png) ### Common Filters - **As Of Date**: This filter snapshots your data at a specific point in time, allowing you to compare dashboards and reports across different dates. You can set the “As Of Date” to view historical data, providing consistency across time periods. - **Partners**: Filter data by cloud partners, such as AWS, GCP, or Azure, to narrow down insights by specific partners. ## View as Table All charts within the dashboard can be viewed as tables, providing a detailed, raw data view behind the visualizations. This option is useful for users who want to analyze data at a granular level, such as verifying numbers or conducting deeper analysis beyond the chart. ![Chart context menu opened on the "Product by Partners" widget, showing options including Force refresh, Enter fullscreen, View query, View as table, and Download](images/image31.png) ![Chart Data table view for "Product by Partners" listing partner and count columns: AWS 46, AZURE 5, GCP 1](images/image1.png) ## Export and Download Fours allows you to download data and visualizations in various formats: - **Export to CSV or Excel**: You can export chart data to CSV or Excel for further analysis or reporting. - **Download Chart Images**: If you need to share or present charts, you can download them as images to include in reports, presentations, or other documents. ![Chart Download submenu on the "Product by Partners" widget, showing Export to .CSV, Export to Excel, and Download as image options](images/image41.png) --- Source: https://doc.fours.com/analytics/craft-dashboards/ # Craft Dashboards ## Create Charts Dashboards in Fours Analytics are built using various types of charts. Before designing a dashboard, you’ll need to create and configure charts first. These charts are reusable and can be shared between different dashboards, ensuring that your data visualizations remain consistent and can be easily updated. ### Steps to Create a New Chart in Fours Analytics 1. **Navigate to Fours Analytics from Console** - Log in to the Fours Console at [Fours Console](https://console.suger.io). - Click the "Analytics" menu item on the left. - Click "Create dashboard". Fours Analytics opens in a new browser tab, where you start creating charts and dashboards. 2. **Create a New Chart** - Navigate to "Charts" by clicking the "Charts" tab in the navigation menu. - Click the "New Chart" button on the top right corner of the "Charts" page to enter the chart creation wizard. - Follow the wizard, choosing the appropriate dataset and chart type. 3. **Design Your Chart** - In the chart design page, drag and drop the required metrics and columns into the appropriate data areas (e.g., X-axis, Y-axis, Legend, etc.). - Customize the chart’s appearance, labels, and other design elements to fit your needs. You can change colors, axis labels, or the chart title to make the chart more informative. ![Chart Design](images/image11.png) 4. **Save the Chart** Once you are satisfied with the chart design, click the "Save" button located at the top right corner. --- ## Create Dashboards Once you’ve prepared your charts, you're ready to start creating dashboards in Fours Analytics. Dashboards help organize and display multiple charts, metrics, and data visualizations in one place, making it easier to gain insights from various aspects of your business or operations. ### Steps to Create a New Dashboard in Fours Analytics 1. **Navigate to Fours Analytics from Console** - Log in to the Fours Console at [Fours Console](https://console.suger.io). - Click the "Analytics" menu item on the left. - Click "Create dashboard" to open Fours Analytics in a new browser tab, where you create your charts and dashboards. 2. **Create a New Dashboard** - Navigate to "Dashboards" by clicking the "Dashboards" tab in the navigation menu. - Click the "New Dashboard" button on the top right corner to enter the dashboard design page. ![Dashboard Design](images/image18.png) 3. **Design the Dashboard** - **Drag and Drop Charts**: On the left drawer, you’ll find all the available charts you’ve created. Drag and drop them onto the dashboard canvas to position them as needed. - **Organize Layout**: Use layout elements (grids, containers, spacers) to keep everything aligned and visually appealing. - **Add Descriptions or Notes**: Drag the "Text/Markdown" element to add explanatory text, descriptions, or markdown-formatted notes. - **Resizing and Moving Elements**: Resize and move elements as needed to fine-tune the layout. ![Dashboard Layout](images/image4.png) ![Dashboard Elements](images/image38.png) 4. **Edit the Dashboard Title** - Click on the title at the top of the dashboard design page to edit it. - Enter a descriptive and relevant title (e.g., "Monthly Sales Overview" or "Customer Acquisition Trends"). 5. **Save the Dashboard** After finalizing the design, click the "Save" button at the top-right corner of the dashboard design page. --- ### Add Filters to Your Dashboard Enhance the interactivity of your dashboard by adding and customizing filters. Filters allow users to dynamically change the data displayed, making it easier to explore specific aspects of the data without altering the dashboard's structure. #### Tips for Effective Filters - **Dynamic Filters**: Enable users to interact with charts directly (e.g., by clicking a chart element to filter data in real-time). - **Clear Naming**: Ensure filters are clearly labeled to indicate their purpose (e.g., "Select Date Range" or "Choose Partner"). - **Limit Filter Options**: Avoid overwhelming users with too many filter options. Keep them relevant to the dashboard's purpose. ### Steps to Add and Edit Filters 1. **Open the Filter Panel** - After saving your dashboard, the filter panel will appear on the right side. Adjust its layout according to your preference. ![Filter Panel](images/image19.png) 2. **Change Filter Panel Orientation** - Click the gear icon on the filter panel to open filter settings. - From the dropdown menu, choose the "Orientation of Filter Bar" option. - You can select "Horizontal (Top)" to position the filter bar at the top or "Vertical (Left)" to place it on the left side. ![Filter Orientation](images/image43.png) 3. **Add or Edit Filters** - Click the gear icon again and select "Add and Edit Filters" to open the filter configuration modal. - **Add a New Filter**: Click "Add Filter" to create a new filter (e.g., date filters, category filters). - **Edit Existing Filters**: Modify any existing filters by clicking on them and updating their settings. ![Filter Settings](images/image43.png) 4. **Configure Filter Details** - Select the filter type (e.g., dropdowns, multi-select lists, date pickers). - Define the scope of the filter, specifying which charts or widgets will be affected. - Set default filter values to load with pre-defined selections. 5. **Save the Filters** After configuring the filters, click "Save" to apply them to the dashboard. --- ### As Of Date Filter The "As Of Date" filter ensures your data is accurately represented at a specific point in time. Without this filter, data might be duplicated or appear multiple times due to missing time-based context. #### Why Add an As Of Date Filter? - **Data Snapshots**: Fours captures data at specific times. Without the filter, the dashboard may show inflated or inconsistent data. - **Prevent Data Explosion**: Without it, the same data may appear multiple times across different dates. - **Time-Based Comparisons**: The filter ensures accurate comparisons across dates. #### How to Add the As Of Date Filter 1. **Open the Filter Configuration** - Navigate to the filter panel and click the gear icon. - Select "Add and Edit Filters" from the dropdown to access the filter configuration modal. 2. **Add a New Filter** - Click "Add Filter" and choose "As Of Date" from the list. ![As Of Date Filter](images/image15.png) 3. **Configure the As Of Date Filter** - **Sort Filter Values**: Set the filter values to display in descending order, ensuring the most recent dates appear first. - **Set Filter as Required**: Mark the "Filter Value is Required" option to ensure users select a valid date. ![As Of Date Settings](images/image55.png) 4. **Set Default Value and Scope** - Set a default date for the filter (e.g., today's date or a pre-set range). - Specify which charts or widgets will be affected by the As Of Date filter. ![As Of Date Scope](images/image50.png) 5. **Save the Filter** After configuring the filter, click "Save" to apply it to your dashboard. --- ### Pin a Dashboard in Fours Console Pinning a dashboard helps keep your most important or frequently used dashboards easily accessible in the Fours Console: each dashboard you pin opens as a tab on your Analytics page. Pins are personal — pinning or unpinning changes only your own Analytics page, not your teammates'. 1. **Navigate to Fours Analytics from Console** - Log in to the Fours Console at [Fours Console](https://console.suger.io). - Click the "Analytics" menu item on the left. - Click the "Choose dashboards" button on the top right corner. If you have not pinned any dashboards yet, the button is in the middle of the page instead. ![Pin Dashboard](images/image49.png) 2. **Pin Dashboards** The **Manage dashboards** dialog lists the dashboards you can pin — your organization's dashboards, plus public dashboards shared with your organization: | Column | What it shows | | --- | --- | | **Dashboard** | The dashboard's title. | | **Access** | **Public** for a dashboard that is shared publicly, **Private** for one only your organization can see. | | **Status** | The status Fours Analytics reports for the dashboard, such as **published** or **draft** — **Unknown** when it reports none. | | **Action** | **Pin** or **Unpin**. The button reads **Saving** while the change is applied. | - Click the "Pin" button to pin a dashboard in Fours Console. - Click "Unpin" to remove it from the pinned list. - Click "Done" to close the dialog. ![Pinned Dashboard](images/image53.png) If the dialog can't load the list, or a pin or unpin doesn't go through, it shows **Couldn’t load available dashboards.**, **Couldn’t pin this dashboard.** or **Couldn’t unpin this dashboard.** with a **Try again** button that reloads the list. **No dashboards are available yet.** means there is nothing to pin yet — create a dashboard with **Create dashboard** first. If a pinned dashboard is deleted in Fours Analytics, or a dashboard another organization shared publicly is made private again, Fours removes it from your pinned dashboards automatically. --- Source: https://doc.fours.com/analytics/available-charts/ # Available Charts Fours Analytics supports a wide variety of chart types, each offering different ways to represent your data. Below are the available chart types: ## Area Chart The Area Chart is perfect for visualizing trends in sales volume or revenue over time. In a marketplace context, you can use it to track monthly or quarterly sales performance, comparing different product categories or partners. Use Case: Sales Over Time, displaying the cumulative sales of different marketplace products or offers over time to understand seasonality or growth pattern. ![Area Chart](images/image47.png) ## Bar Chart The Bar Chart is useful for comparing sales data across different categories or products. It allows you to quickly identify top-performing items and underperforming ones. Use Case: Sales by Product/Category, comparing the sales volume of different marketplace products, cloud partners (e.g., AWS, Azure, GCP), or sales regions. ![Bar Chart](images/image45.png) ## Big Number This chart is ideal for showcasing a single, significant metric. You can highlight the total revenue or sales for a specific time period or other vital KPIs. Use Case: Key Marketplace Metrics, display the total marketplace revenue for a given month or the number of new marketplace entitlements sold. ![Big Number](images/image37.png) ![Big Number with Trendline](images/image8.png) ## Box Plot A Box Plot is a statistical visualization used to display the distribution of a dataset, including key summary statistics like the median, quartiles, and outliers. It's particularly useful for understanding the spread and variation in data. Use Case: Sales Volume Across Different Partners, in a marketplace where multiple partners (AWS, Azure, GCP) are selling products, a Box Plot can help you understand if the sales volume is consistent across partners or if some have periods of exceptionally high or low sales. ![Box Plot](images/image29.png) ## Bubble Chart A Bubble Chart is a type of chart that uses bubbles to represent data points on a 2D plane. Each bubble’s position on the chart represents two variables, and its size represents a third variable. This allows you to visualize three dimensions of data at once. A Bubble Chart is particularly useful when you want to visualize relationships between three variables (for example, sales performance, number of units sold, and customer engagement) in a marketplace setting. Use Case: Sales by Product, * X-axis: Represents the total units sold. * Y-axis: Represents the average order value (or revenue per order). * Bubble Size: Represents the total sales revenue for that product. * Bubble Color: Represents different product categories (e.g., electronics, clothing, etc.). ![Bubble Chart](images/image39.png) ## Bullet Chart Helps measure performance against a target, often used to compare actual sales to projected or goal figures. Use Case: Performance Against Goals, show how monthly sales are tracking against a set sales target for the marketplace. ![Bullet Chart](images/image51.png) ## Calendar Heatmap Shows daily sales activity on a calendar grid, with color coding to indicate activity levels. Use Case: Sales Activity by Date, visualize daily sales trends for a specific marketplace product or offer. ![Calendar Heatmap](images/image22.png) ## Chord Diagram Displays relationships between different entities. Use Case: Interconnections Between Entities, visualize how sales in different marketplace product categories connect to partner sales reps or buyers. ![Chord Diagram](images/image46.png) ## Country Map Provides a map view showing sales in different countries. Use Case: Global Sales Distribution, track sales performance in various countries where the marketplace operates. ![Country Map](images/image7.png) ## Funnel Chart A Funnel Chart is well-suited for visualizing the conversion rate of users or leads through a sales process. In marketplace sales, this could represent how many users progress through stages like product views, cart additions, checkout, and purchases. Use Case: Sales Conversion Process, tracking the sales funnel from initial product views to completed purchases in the marketplace, showing where potential customers drop off. ![Funnel Chart](images/image14.png) ## Gauge Chart Tracks performance against a goal, similar to a speedometer. Use Case: Progress Monitoring, monitor current marketplace revenue against a set target. ![Gauge Chart](images/image6.png) ## Generic Chart A more flexible chart type for custom data representations. Use Case: Customizable Visualizations, can be used to create tailored visualizations specific to the marketplace’s needs. ![Generic Chart](images/image52.png) ## Graph Chart Represents relationships between entities, like users, products, or partners, in a network format. Use Case: Network Analysis, visualize the relationships between marketplace products and cosell partners. ![Graph Chart](images/image10.png) ## Heatmap The Heatmap chart is effective for showing sales activity across different time intervals, such as days, weeks, or months. It highlights when sales are peaking and can identify patterns in customer behavior or sales cycles. Use Case: Sales Activity by Time, visualizing sales activity by day and time, helping you identify the most profitable days or hours for sales in the marketplace. ![Heatmap](images/image26.png) ## Histogram A Histogram helps you understand the distribution of sales, whether it’s the number of units sold per product or the price range of items purchased. Use Case: Sales Distribution, displaying the distribution of average order value or the number of items sold within specific price ranges. ![Histogram](images/image34.png) ## Horizon Chart Similar to line charts but with color bands to indicate magnitude. Use Case: Trends Over Time, track changes in total marketplace revenue over time. ![Horizon Chart](images/image32.png) ## Line Chart The Line Chart is great for showing continuous trends, such as daily, weekly, or monthly sales figures. It’s perfect for tracking sales growth and forecasting future trends. Use Case: Sales Trends Over Time, tracking marketplace sales growth over time and comparing performance across different products or regions. ![Line Chart](images/image3.png) ## Mixed Chart Combines two chart types into one visualization for comparison. Use Case: Combining Multiple Chart Types, compare sales volume alongside customer ratings using a mix of line and bar charts. ![Mixed Chart](images/image33.png) ## Nightingale Rose Chart A variant of the radar chart, useful for comparing categories around a central point. Use Case: Comparing Categories, compare sales performance of marketplace products based on different metrics. ![Nightingale Rose Chart](images/image36.png) ## Paired t-test Table Used for statistical analysis of two sets of data to see if there’s a significant difference. Use Case: Statistical Comparison, compare sales before and after a promotional campaign in the marketplace. ![Paired t-test Table](images/image23.png) ## Parallel Coordinates Visualizes data with multiple variables in parallel axes. Use Case: Multivariate Data Analysis, compare product sales, revenue, and user engagement across several products. ![Parallel Coordinates](images/image12.png) ## Partition Chart Visualizes hierarchical data in a tree-like structure. Use Case: Hierarchical Data Representation, visualize how marketplace sales are distributed across different product categories and subcategories. ![Partition Chart](images/image20.png) ## Pie Chart The Pie Chart is useful for visualizing the relative share of marketplace sales across different categories or products. Use Case: Sales Distribution, showing the percentage of sales generated by different product categories (e.g., software, hardware) or cloud partners (AWS, Azure, GCP). ![Pie Chart](images/image16.png) ## Pivot Table Summarizes large datasets, allowing quick exploration of key metrics. Use Case: Data Summarization, used to summarize sales data by region, product, or partner. ![Pivot Table](images/image9.png) ## Radar Chart The Radar Chart is useful for comparing multiple variables at once. In the marketplace, it can show how different sales metrics (e.g., revenue, customer satisfaction, inventory levels) perform across different products or categories. Use Case: Comparing Marketplace Metrics, comparing the sales performance of different marketplace products on multiple dimensions, such as revenue, customer ratings, and return rates. ![Radar Chart](images/image35.png) ## Sankey Chart A Sankey Chart visualizes the flow of data, making it ideal for understanding how marketplace sales revenues are distributed across different sources or stages. Use Case: Sales Flow Analysis, visualizing how revenue flows from product categories to individual sales reps, or how sales are split between marketplace offers (e.g., discounted vs. regular priced). ![Sankey Chart](images/image21.png) ## Scatter Plot The Scatter Plot is helpful for visualizing the relationship between two variables, such as sales volume and customer engagement. Use Case: Sales by Product vs. Customer Engagement, plotting sales volume on the x-axis and customer satisfaction scores on the y-axis to see if there’s a correlation between product popularity and customer ratings. ![Scatter Plot](images/image24.png) ## Smooth Line Similar to a line chart, but with a smoothed curve to make trends easier to spot. Use Case: Trend Analysis, track the trend of marketplace revenue while filtering out short-term fluctuations. ![Smooth Line](images/image42.png) ## Stepped Line Shows trends in a stepped format, useful for data that changes at discrete intervals. Use Case: Discrete Trends, track sales changes at different time intervals in the marketplace. ![Stepped Line](images/image25.png) ## Sunburst Chart Visualizes hierarchical data in a circular structure. Use Case: Hierarchical Data Exploration, show sales breakdown by product category and subcategories. ![Sunburst Chart](images/image40.png) ## Time-series Table A Time-series Table displays data over time in a tabular format, allowing users to track the changes in metrics such as revenue, units sold, customer acquisition, and other key performance indicators (KPIs) over specified time intervals. ![Time-series Table](images/image27.png) ## Tree Chart The Tree Chart is effective for visualizing hierarchical data, such as sales across multiple levels of a product hierarchy. Use Case: Hierarchical Sales Data, visualizing how sales are distributed across product categories, subcategories, and individual items within the marketplace. ![Tree Chart](images/image5.png) ## Treemap A Treemap displays hierarchical data in nested rectangles, ideal for showing how marketplace sales are distributed across various product categories or sales regions. Use Case: Sales Hierarchy by Product/Category, a treemap can show the proportion of total sales made by different marketplace product categories (e.g., software, services) or by cloud partners (AWS, GCP, Azure). ![Treemap](images/image28.jpg) ## Waterfall Chart The Waterfall Chart is excellent for visualizing the incremental change in sales or revenue over time or across different business units. Use Case: Revenue Change Analysis, visualizing how revenue changes month-over-month, showing how new product launches or seasonal promotions contribute to overall sales. ![Waterfall Chart](images/image30.png) ## Word Cloud The Word Cloud helps analyze customer feedback and reviews by visualizing the most frequently mentioned keywords or phrases. Use Case: Customer Feedback Analysis, creating a word cloud from customer reviews of marketplace products to identify common themes, such as satisfaction with features or concerns with usability. ![Word Cloud](images/image17.png) ## World Map A World Map is a type of visualization that represents geographical data using a map of the world. It is particularly useful for displaying metrics that vary across different regions or countries, such as sales performance, customer acquisition, or market share. Use Case: Global Sales Distribution, This helps you quickly identify the top-performing countries or regions and those that are underperforming. * Metric: Total sales revenue from each country or region. * Visualization: Countries are color-coded based on total revenue (e.g., red for high revenue, blue for low revenue). ![World Map](images/image54.png) --- Source: https://doc.fours.com/analytics/available-datasets/ # Available Datasets Fours provides a variety of datasets to support the creation of tailored dashboards, enabling you to visualize and analyze data from multiple sources. Each dataset includes key metrics for direct use and dimensions for analysis. Users can access and customize charts based on their needs. Below are some of the basic datasets that come out of the box: * **billing\_revenue\_record**: Contains detailed records of revenue generated through various billing channels, providing insights into business performance and financial metrics. * **marketplace\_entitlement**: Tracks customer entitlements for marketplace products or services, helping you understand the usage rights and access levels associated with your offerings. * **marketplace\_offer**: Includes data on marketplace offers, including public and private offers, enabling you to analyze offer performance and customer engagement. * **marketplace\_product**: Contains information about products listed in the marketplace, including product details, pricing, and availability, giving you insights into product sales and demand. * **identity\_user\_organization\_relationship**: Tracks your internal employees within the Fours platform, helping you visualize and manage user access and roles. * **identity\_user**: Contains employee profile information, enabling you to analyze user activity. * **identity\_organization**: Your organization's basic profile. * **identity\_buyer**: Includes buyer profile data, such as company name, industry, contacts and locations, to analyze buying patterns and improve targeting. * **cosell\_referral**: Contains data on cosell referrals, helping you track co-selling activities and referral performance between partners, providing insights into collaborative sales efforts. --- Source: https://doc.fours.com/analytics/ # Analytics Fours Analytics charts the data already in your Fours organization — revenue records, entitlements, buyers, co-sell referrals, and your own users — without exporting it to another tool first. It runs at [console.suger.io/analytics](https://console.suger.io/analytics), ships with built-in dashboards you can use as they are, and lets you build your own on top of the same datasets. The building block is a **chart**, not a dashboard. You create a chart against one dataset, and that chart is reusable — several dashboards can show it, so a metric stays defined in one place. Dashboards then add filters on top, so a single dashboard answers a range of questions instead of needing a copy per segment. ## What you can do - Create a chart from a dataset and pick from a wide catalog of visualizations — area, bar, big number, funnel, heatmap, country map, and more. - Assemble charts into a dashboard, add filters to it, and pin it — or a public dashboard shared with your organization — so it opens as a tab on your Analytics page. - Scope a dashboard by time with the **As Of Date** filter, or by whatever dimensions the underlying dataset exposes. - Switch any chart to **View as Table** to see the rows behind it, then export and download the data. Start with the **[Quick Guide](/analytics/quick-guide/)** to open Analytics, pin a dashboard, and learn the filter, table, and export controls. When you are ready to build, **[Craft Dashboards](/analytics/craft-dashboards/)** walks through creating a chart, assembling it into a dashboard, adding and editing filters, and pinning the result. Two references support that work. **[Available Charts](/analytics/available-charts/)** describes each chart type and the marketplace question it suits — which one to reach for when you want sales over time versus a category comparison. **[Available Datasets](/analytics/available-datasets/)** lists the datasets that come out of the box, including `billing_revenue_record`, `marketplace_entitlement`, `cosell_referral`, and `identity_buyer`, with the metrics and dimensions each one carries. ## Scope and limits :::info Analytics reads the data Fours already holds for your organization, through the out-of-the-box datasets described above. If a metric you need is not carried by one of those datasets, it cannot be charted here — check the dataset reference first when planning a dashboard. ::: The Analytics page also shows a banner, **Analytics is moving to Insulin Custom Apps**, with an **Open Custom Apps** button. Your existing dashboards keep working here until the page is retired; they are not moved across automatically. [Custom Apps](/insulin/custom-apps/#build-dashboards-with-ai) explains how to build a dashboard there by describing what you need in plain English, and how to get help migrating. --- Source: https://doc.fours.com/prm/navigate-the-partner-console/ # Navigate the Partner Console Find your way around the Partner Console so you know where to go at each stage of a partner relationship. --- ## Overview The Partner Console lives under **Partners** in the Fours Console, and its rail covers two kinds of work: - **Settings**, the last item in the rail, where you configure your partner program. - **Everything above it**, where you recruit, onboard, and collaborate with partners every day. This guide gives you a tour of both. For detailed instructions, follow the how-to guides linked from each section. ## The Partners Rail The main areas under **Partners** are reached from a rail on the left, split into two groups, with **Settings** below them. The top group opens with **Dashboard**, then follows the partner lifecycle — the stages a relationship passes through: | Item | What it's for | | --- | --- | | **Dashboard** | Your whole program at a glance: what needs attention today, how the program is performing, how each partner manager's book is doing, and where your partners are. | | **All Partners** | Your directory of partner records. | | **Applications** | Every partner application you've received, whether pending, accepted, declined, or expired — and, for Admins, requests to join your organization. | | **Partner Discovery** | Candidates to recruit, from AI recommendations or your CRM. | | **Journeys** | Onboarding playbooks and the partners working through them. | | **Partner Co-Sells** | Shared sales opportunities in both directions. | The second group is headed **Workspace** — the tools you use *across* partners rather than at one stage: | Item | What it's for | | --- | --- | | **Tasks** | Follow-ups and action items. | | **Partner Files** | The shared document library. | | **Training** | Courses, progress, and certificates. | | **Events** | Webinars, training sessions, and partner events, with RSVPs. | | **Broadcasts** | One message sent to every partner's Slack channel at once. | Below the Workspace group, **Settings** (the gear icon) opens your partner program's configuration — your partnership profile, brand, login page, sign-up forms, commissions, journey templates, file sharing defaults, tiers, and more — with its own list of sections. See [Set Up Your Partner Program](#set-up-your-partner-program). Opening **Partners** lands on **All Partners**, even though **Dashboard** sits above it. Selecting a rail item swaps the main column — it doesn't navigate away — so the rail stays put as you move between sections. You can collapse it to an icon-only strip when you want the width. In a browser window narrower than 1,280 pixels, the rail gives way to a section picker under the **Partners** heading, which lists the same items, **Settings** included. ![The Partners rail — Invite Partners at the top, then All Partners, Partner Discovery, Journeys and Partner Co-Sells, followed by the Workspace group with Tasks, Partner Files, Training, Events and Broadcasts](images/30-partners-rail.png) ### What You See Depends on Your Organization Not everyone sees all twelve items. - **Dashboard**, **Applications**, **Partner Discovery**, **Journeys**, and **Broadcasts** are seller-side tools. If your organization joined Fours as a partner rather than running its own partner program, these five are hidden, because there is no program of yours to measure, and nobody applying to you, for you to discover, to onboard, or to broadcast to. - **Partner Co-Sells** and **Training** each depend on their own feature being enabled for your organization. - **Settings** appears for seller, reseller, and partner organizations. - **If your organization joined as a partner and has a single partnership**, opening **Partners** takes you straight to that partnership's record. The exception is an invitation from another company that is still waiting for your answer: then the list stays open, so you can answer it under **Pending invitations**. The **Home** button at the top left always opens the list. If an item named in this guide isn't in your rail, that's why. Check with your Fours admin rather than hunting for it. ## Set Up Your Partner Program Before inviting partners, spend a few minutes configuring the core settings under **Partners → Settings**, the last item in the rail. These define how your partner program works. ## How Partners Move Through the Console Once your program is set up, a partner relationship generally moves through the console in this order: 1. **Find or invite a partner** in Partner Discovery, or let one apply through a sign-up form. Applications wait under **Applications** for you to approve or decline. 2. **Track the invitation** while it's pending. An invited company is listed in All Partners from the moment you send, with the status `PENDING`. See [Collaborations](#collaborations). 3. **Once they accept**, the partner turns `ACTIVE`. Assign them a Journey to guide them through onboarding. 4. **As they become active**, co-sell opportunities with them surface in Partner Co-Sells. 5. **Throughout the relationship**, use Tasks to keep action items on track, Partner Files to share documents, and Training to certify them on your product. ![Overview of how partners move through the Partner Console](images/navigate-the-partner-console-1.png) The sections below walk through each stop along that path. ## Partner Discovery Partner Discovery is split into three sub-tabs, one per source: | Sub-tab | Where the candidates come from | | --- | --- | | **Recommended Partners** | Companies Fours surfaced from the partner, referral, CRM, and co-sell data in your account, ranked by likely revenue impact. | | **From Your Marketplace** | Resellers you have already transacted with on a cloud marketplace, with the revenue and deal counts to prove it. | | **From Your CRM** | Salesforce accounts that match your saved discovery filter, once your CRM connection is set up. | From here, you can review the candidates and click **Invite** on the ones worth pursuing, or select several and click **Invite Selected**. ![Partner Discovery page in the Partner Console](images/navigate-the-partner-console-2.png) ## Collaborations Collaborations are the conversations you're having with partners, whether you started them (Outbound) or they came to you (Inbound). There's no separate page for them: - **Invitations you send** are rows in **All Partners**, listed as `PENDING` until the partner answers. While an invitation is waiting, the row's **⋯** menu carries **Resend invitation** and **Cancel invitation**. - **Requests that come to you**, from your sign-up form or from another Fours organization, wait under **Applications**. Check your `PENDING` partners regularly, and resend to the ones that have gone quiet. See [Track Partner Collaborations](/prm/collaborations/). ![Collaborations page in the Partner Console](images/navigate-the-partner-console-3.png) ## Applications **Applications** lists every request to partner with you. That includes submissions from your public registration form and invitations other Fours organizations send you in the app. Filter the list by status (**Pending**, **Accepted**, **Declined**, or **Expired**), and approve or decline the rows that are still pending. This list keeps the applications you've already decided, including the ones you turned down. See [Track Partner Collaborations](/prm/collaborations/). If you're an Admin, **Applications** has two sub-tabs: **Partnership**, the applications described above, and **User access**, the people asking to join your own organization. See [Review requests to join your organization](/prm/collaborations/#review-requests-to-join-your-organization). ## All Partners Partners you invite appear in **All Partners** as soon as the invitation goes out, with the status `PENDING`, and turn `ACTIVE` once they accept. This is your main directory for managing partner relationships. Use filters to quickly find partners by type, channel, partner manager, or tier. The **Partner Manager** filter lists your teammates from A to Z: type in **Search managers…** to find one by name or email, and the managers you've already picked stay at the top of the list. From here, you can open partner profiles, review their details, update information, and access their related activity. Until an invited partner answers, its row's **⋯** menu also carries **Resend invitation** and **Cancel invitation**. If the partner record has no contact of its own yet, the row shows the person you invited, and **Email not sent** appears under the contact email when the invitation email couldn't be sent. See [Invite Partners](/prm/invite-partners/#invitation-status-and-expiry). ![All Partners directory in the Partner Console](images/navigate-the-partner-console-4.png) Opening a partner gives you their record, itself split into sections down the left: **Overview**, **Co-Sell**, **Commissions**, **Marketplace**, **Journeys**, **Tasks**, **Resources**, **Events**, **Training**, and **Agreements**. For what each section holds and how to work one, see [Work a Partner Record](/prm/work-a-partner-record/). :::info **Marketplace** is the section that shows a partner's marketplace transactions. ::: ## Journeys Journeys are onboarding plans built from reusable templates. Each assigned Journey tracks a partner's progress through onboarding so you can quickly see who's active, completed, or stalled. From here, you can assign onboarding plans to new partners and monitor their progress over time. ![Journeys page in the Partner Console](images/navigate-the-partner-console-5.png) ## Partner Co-Sells Partner Co-Sells brings together shared sales opportunities between you and your partners. Each opportunity shows its direction, current status, and linked Salesforce Opportunity ID when Salesforce is connected. From here, you can accept new co-sell opportunities, monitor active deals, and collaborate with partners throughout the sales cycle. ![Partner Co-Sells page in the Partner Console](images/navigate-the-partner-console-6.png) ## Tasks Tasks help you track follow-ups, document requests, approvals, and other action items for individual partner relationships. Each task has a **Direction** that shows who needs to act next. **`Outbound`** means your team has work to do, while **`Inbound`** means you're waiting on the partner. If you regularly create the same set of tasks, use a **Template** to create them all at once instead of adding them individually. ![Tasks page in the Partner Console](images/navigate-the-partner-console-7.png) ## Partner Files **Partner Files** is a shared library for resources you want partners to access, such as sales collateral, onboarding guides, product documentation, marketing assets, and legal documents. Files are organized into categories, and each category can have default sharing permissions configured in **Partners → Settings → File Sharing Defaults**. From here, you can upload resources, choose who can access them, and organize them into categories so partners can easily find what they need. ![Partner Files library in the Partner Console](images/navigate-the-partner-console-8.png) ## Training **Training** lets you create learning content for your partners and track their progress. Partners can also share their own training with your team, making it a central place to manage enablement in both directions. Alongside courses, the Training area includes **Certificates** for recognizing course completion and **Partner Progress** for monitoring how partners and individual learners are progressing. From here, you can create onboarding or certification courses, review completion progress, and manage certificates for partners who complete your training. Check **From Partners** when partners have shared training with your team. ![Training page in the Partner Console](images/navigate-the-partner-console-9.png) ## Events **Events** is a single feed of webinars, training sessions, and partner events. Create an event, share it with partners, and they RSVP from their own portal. The **All**, **Shared**, and **Received** tabs slice the feed by who owns each event. Events you own show an RSVP count and let you work the attendee roster; events shared *to* you offer **Attending** and **Decline** instead. The same set can be read as a list or on a calendar. Partner organizations can RSVP but cannot create events. ![The Events feed — the All / Shared / Received tabs, event rows with their type badges and RSVP counts, and the Create Event button](images/34-events-list.png) See [Create and Share Partner Events](/prm/partner-events/). ## Broadcasts **Broadcasts** sends one message to every partner's Slack channel at once, then collects the replies and reactions in one place so you can see who engaged. Use it for the announcements you'd otherwise paste into a dozen channels by hand — a release, a program change, a deadline. See [Send a Broadcast to Your Partners](/prm/broadcasts/). Broadcasts post into Slack, so they depend on your workspace being connected and a channel being mapped to each partner first — see [Connect Slack for Your Partners](/prm/connect-slack-for-partners/). ## Dashboard **Dashboard**, at the top of the rail, reads the whole program back to you in four tabs: **Today** for what needs you now, **Performance** for pipeline, co-sell, commissions and enablement, **Team** for each partner manager's book, and **Footprint** for where your partners are. Filters for marketplace, partner type, tier, and **My partners** narrow every tab at once, and each row that needs action links to the place you act on it. See [Partner Program Dashboard](/prm/partner-program-dashboard/). ## Working With PRM Tables The lists across PRM behave the same way, so what you learn on one table carries to the next. - **An Actions column.** Every row's actions live behind the kebab (**⋯**) menu in the trailing **Actions** column, rather than being spread across the row. Destructive choices such as **Delete** are marked in red. - **A Columns chooser.** The **Columns** button opens a checklist of every available column. Your choice is remembered per table and per browser, so a table you trimmed stays trimmed the next time you open it. - **Definitions on the numbers.** A count or metric with an ⓘ beside it — a tile, a progress bar, a total — shows what it counts when you hover over the ⓘ or tab to it. Where the count sits inside a tab or an expandable header, such as **All Tasks** and **My Tasks**, or the **N deal registrations from email** bar, hover over or tab to the tab or header itself. Some counts are narrower than they look: on the **Tasks** page, the **Open**, **In Progress**, and **Blocked** counts cover only the tasks on the current page, after your filters. - **Filters above the table.** Each list carries the filters that make sense for it — status, owner, tier, direction, and so on. Filters apply to the list you're looking at and reset when you navigate away, so set them for the task at hand rather than expecting them to stick. The **All Partners** list adds a **Filters** popover for more precise, multi-field searches. Unlike the quick filters, a saved advanced filter *is* remembered and re-applied the next time you open the list. --- Source: https://doc.fours.com/prm/complete-partnership-profile/ # Complete Partnership Profile Set up the profile partners see when they view your company in Fours — your identity, relationship type, capabilities, portal URL, and access settings. --- ## Overview Your **Partnership Profile** is what partners see when they view your company inside Fours. It also stores the information used for your partnership capabilities and company identity, so it's one of the first things you should complete before inviting partners. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Step 1: Access your Partnership Profile settings 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Partnership Profile**. Until every field marked with a red asterisk is saved, the rest of **Partners** shows **Complete your partnership profile** instead, and its **Complete Partnership Profile** button brings you here. **Settings** stays open while your profile is incomplete, so you can finish it. ![Partnership Profile settings under Settings > Partner in Fours Console](images/complete-partnership-profile-1.png) ## Step 2: Fill in your company identity ### Auto-fill from your website Before filling out your profile manually, you can have Fours generate a first draft from your company website. At the top of the page, click **Generate from Domain**. Fours uses AI to generate your profile content based on information from your website. Review the generated content carefully before saving. It's intended as a starting point and may need edits to accurately reflect your company. **Generate from Domain also finds a logo.** Fours looks for one on your website and, if it finds a usable image, stores it as your profile logo alongside the generated text. When it does, a notice appears under the **Logo** field: > This logo was found automatically on your website. Check it's the right one before saving — it may have picked a social banner or an icon. Take that seriously. Automatic logo detection reads the images a homepage advertises about itself, which is often the right logo and sometimes a social-sharing banner or a favicon. Replace it with an upload if it isn't what you want partners to see. :::info The logo is only best-effort. If nothing usable can be found or stored, the rest of the generated profile still saves and the **Logo** field is simply left for you to fill in. ::: ![Generate from Domain button that drafts profile content from your website](images/complete-partnership-profile-2.png) ### Identity The Identity section covers the basic details partners will see about your company. Work through each field in order: 1. **Company Name** — Your official company name as you want it displayed to partners. 2. **Logo** — Upload your company logo. PNG or JPG only, 2 MB max. 3. **Headline** — A short, one-line summary of what your company does (120 characters max). Think of this as your tagline — it's the first thing a partner reads about you. 4. **Description** — A fuller explanation of your business: what you do, who you serve, and why it matters to a partner (500 characters max). Both Headline and Description show a live character counter, so you'll see exactly how much room you have left as you type. 5. **Website** — Your company's main website URL. 6. **Partnership Contact Email** — The email address partner inquiries should go to. Use an inbox your team actually monitors, not a personal address, since this is what partners will use to reach you. ![Identity section fields including company name, logo, headline, description, website, and contact email](images/complete-partnership-profile-3.png) ## Step 3: Set your Relationship Type Relationship Type defines *whose product is being sold* in co-sells your organization initiates. Choose one: | Option | What it means | | --- | --- | | **Our product is being sold** | You are the Seller — your product is what's typically being sold in a deal. | | **The partner's product is being sold** | The partner is the Seller — you're usually the one referring or supporting someone else's sale. | | **Both products can be sold** | Either direction is possible depending on the deal. | This is required before your first co-sell, and it determines what the next section is called and which capabilities you'll see in it. :::info On an individual partner's record the middle option names that partner instead — for example, *"Acme Corp's product is being sold"* — so you can see at a glance which way round that specific relationship runs. It's the same setting. ::: ![Relationship Type options for whose product is being sold](images/complete-partnership-profile-4.png) ## Step 4: Choose your capabilities The section below **Relationship Type** changes based on what you picked. ### If you selected "Our product is being sold" You'll see a section called **What We're Open To** ("What can partners do with/for us"). Check off any that apply: * **Refer leads to us** — Partners send you customers, and you pay them a referral fee when deals close. _In practice: this is the lowest-commitment option. There's no resale agreement involved — just a lead-passing relationship with a payout tied to it._ * **Resell our product** — Partners sell your product under their own agreement and earn a margin. _In practice: this needs a formal resale agreement in place (a Resale Authorization, or CPPO_OUT, when you're issuing it — for example, AWS's Reseller Contract for AWS Marketplace). You won't see the partner's final markup or end-customer price; that stays private to them._ * **Sell together** — You jointly pursue and close deals, sharing the opportunity. _In practice: this is a co-sell relationship. Deals get registered and tracked jointly, and both sides typically have visibility into where the deal stands._ * **Build an integration** — You connect your products technically to create a better experience for shared customers. _In practice: this is a product or engineering commitment, not just a go-to-market one, so it usually involves more than your partnerships team alone._ ![What We're Open To capability checkboxes for sellers](images/complete-partnership-profile-5.png) ### If you selected "The partner's product is being sold" You'll see a section called **What We Offer** ("What we bring to a partnership"). Check off any that apply: * **We refer customers to you** — You have customer relationships you can refer their way. _In practice: the mirror of "Refer leads to us" — you're the one sending business, and the payout structure runs the other direction._ * **We resell your product** — You have sales channels and can sell their product. _In practice: this puts you on the hook for a resale agreement (the marketplace calls this a Resale Authorization, or CPPO_IN, when you're receiving it). You control the final markup and price to the end customer; the ISV won't see those numbers._ * **We sell together** — You partner with sellers to jointly close deals. _In practice: same co-sell tracking as above, just with you playing the reseller or partner role instead of the seller._ * **We integrate with your product** — You connect your services with their product to deliver better outcomes. _In practice: another technical commitment — worth confirming your product team is aligned before you check this box._ ![What We Offer capability checkboxes for partners who resell](images/complete-partnership-profile-6.png) ### If you selected "Both products can be sold" You'll see a section called **Partnership Capabilities**, showing both the "What We're Open To" and "What We Offer" options together, since either side could apply depending on the deal. Both sets of checkboxes appear on the same screen — see the two lists above. Check off only the capabilities that reflect real, current arrangements you're willing to support. These selections shape what partners understand is possible when they engage with you, so leave unchecked anything you're not ready to do yet. ![Partnership Capabilities section combining both open-to and offer options](images/complete-partnership-profile-7.png) ## Step 5: Set your Partner Portal URL Your portal slug is the part of your portal's web address that comes after `console.suger.io/prm/`, typically your company name (for example, `acme-partners`). It isn't set on this page: the **Partner Portal URL** card lives under **Partners → Settings → Login Page**, next to the login URL it builds. 1. Go to **Partners → Settings → Login Page**. 2. Enter the slug under **Portal Slug**, then click **Save**. The slug also builds your public deal registration link, so once it's saved, changing it breaks the links your partners already have — Fours asks you to confirm first. See [Choose your portal slug](/prm/partner-portal-login-page/#choose-your-portal-slug). ![Partner Portal URL field where you set your portal slug](images/complete-partnership-profile-8.png) ## Step 6: Decide your Partnership Access Under **Partnership Access**, use the toggle to choose how organizations can connect with you: * **Open (toggle on):** Anyone can send your organization a partnership request. * **Invite Only (toggle off):** Only organizations you invite can establish a partnership. ![Partnership Access toggle for Open or Invite Only](images/complete-partnership-profile-9.png) ## Step 7: Save your profile Once every section above is filled in, click **Save Profile** at the bottom of the page. Nothing here is permanent — you can return and update your identity, capabilities, or access setting at any time as your partner program evolves. ## What partners see Once saved, your **Company Name**, **Website**, and **Description** appear on your profile when a partner views their relationship with you. Partners will also see additional details on this same page, like your tier in their program and company specializations, but those come from other Fours settings, not from Partnership Profile. ![Partner-facing view of your company profile showing name, website, and description](images/complete-partnership-profile-10.png) --- Source: https://doc.fours.com/prm/brand-settings/ # Brand Settings Brand settings control how your company appears to partners — your brand colors and an optional tagline. --- ## Overview The **Brand** settings control how your company appears to partners. This is where you choose your brand colors and add an optional tagline. These settings apply only to the parts of Fours that represent your company, such as your Partner Profile, banner, sidebar cards, and white-label portal. The rest of the Fours interface keeps its standard branding. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Access your Brand settings 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Brand**. ![Brand settings under Partner in Fours Console Settings](images/complete-brand-settings-1.png) ## Update your brand identity As you update each field, the **Live Preview** panel refreshes automatically to show how your Partner Profile will appear to partners. Use the preview to make sure your colors and tagline look the way you expect before saving. ![Brand settings form with Live Preview panel](images/complete-brand-settings-2.png) ### Where your logo lives The **Brand** tab no longer uploads a logo. It only sets your colors and tagline, and *reads* your existing logo so the **Live Preview** panel can show it in context. Your logo is set under **Partners → Settings → Partnership Profile**, and the same stored logo is used everywhere your brand appears — Partner Profile, banner, sidebar cards, and the white-label portal. Change it there and the preview here picks it up on the next load. If no logo is set, your organization's initials are shown instead. ### Set your primary color Enter your brand's primary color as a hex code (for example, `#F26A1C`). This color is used for your banner, sidebar card headers, action buttons, active tabs, and link accents. For the best appearance, choose a darker, saturated color if possible. The banner automatically adjusts the background to keep white text readable, so very light or pastel colors generally produce less contrast. ### Set your secondary color (optional) Enter a hex code for card borders and accent highlights (for example, `#FBB92A`). If you leave this blank, Fours automatically generates a secondary color from your primary color. Only set this field if you want more control over your accent color. ### Add a banner tagline (optional) Enter a short line that appears beneath your company name and tags on your Partner Profile. The tagline can be up to 80 characters long, and a live character counter shows how many characters you've used. If you leave this blank, no tagline is shown. ### Save your changes Click **Save Brand**. Changes appear the next time a partner views your profile. ![Save Brand button on the Brand settings page](images/complete-brand-settings-3.png) ## What Brand Settings Don't Control Brand settings decide how your company *looks* to a partner. They don't decide what a partner *reads* when they land in the portal. To choose the content on a partner's portal Overview — which cards appear, in what order, and what each one says — see [Customize the Partner Portal Overview](/prm/customize-the-partner-overview/). --- Source: https://doc.fours.com/prm/partner-portal-login-page/ # Partner Portal Login Page Give partners a branded way to sign in to your Partner Portal with a custom login page. --- ## Overview The **Login Page** settings let you share a unique Partner Portal login URL directly, or embed it on your website, so partners arrive at a login page that matches your company's branding. This step is optional. Partners can already sign in to Fours without a custom login page — enabling one simply provides a more consistent, branded experience. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Access Your Login Page Settings 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Login Page**. ![Login Page settings under Settings → Partner in the Fours Console](images/set-up-your-partner-portal-login-page-1.png) ## How Branding Works - Your **logo** and **organization name** are automatically pulled from your Brand settings. - The login page headline and supporting text are managed by Fours and can't be customized. - To update your logo or other brand assets, see [Brand Settings](/prm/brand-settings/). ## Set Up Your Login Page ### Choose your portal slug The **Partner Portal URL** card at the top of the tab sets your portal slug, the last part of your partner portal address (`console.suger.io/prm/{your-portal-slug}`). The login URL and HTML snippet below are built from it. 1. Under **Portal Slug**, enter the slug, for example `acme-partners`. It must be 3–63 characters, start with a letter, and use only lowercase letters, numbers, and single hyphens between them. 2. Click **Save**. Fours confirms with *"Portal slug saved."* Slugs are unique across Fours, so if yours is taken, Fours says so and you pick another. The same slug also builds your [public deal registration link](/prm/public-deal-registration-link/). Changing or clearing a slug you've already saved breaks every link your partners have, so Fours asks first — **Change your portal slug?** or **Clear your portal slug?** — and warns that the old URLs will stop working and show a "not found" page. Click **Change it** or **Clear it** to go ahead, or **Keep current slug** to back out. Setting a slug for the first time saves straight away. ### Enable the custom login page The **Enable Custom Login Page** toggle controls whether partners see your branded login page or the default Fours login page. - **On:** Partners see your branded login page, including your logo, organization name, and optional background image. It asks for their work email first, then shows each partner the next step that fits them. See [What Partners See When They Sign In](#what-partners-see-when-they-sign-in). - **Off:** Partners see the standard Fours login page. The login URL itself doesn't change. The toggle decides which page partners get after opening the link, and with it whether their work email is checked before they sign in. ### Copy your partner login URL Your **Partner Login URL** is the dedicated link partners use to access your portal. - Click **Copy URL** to copy the link and share it directly with partners. - Click **Open** to preview the login page in a new browser tab. ### Embed the login link on your website Under **Ready-to-paste HTML snippet**, click **Copy HTML** to copy a ready-to-use login link for your website. Paste the snippet wherever you want partners to access your Partner Portal. No additional HTML is required unless you want to customize its appearance. ### Add a background image (optional) The background image appears behind your branding on the custom login page. Click **Upload New File** to upload a PNG or JPG (up to 3 MB). Fours recommends an image that's approximately 1200 × 900 px. If you don't upload a background image, the page uses your brand's primary color instead. ### Brand the sign-in form (optional) Your branded login page is the first screen partners see. After they click **Log In** or **Create your account** there, they reach the sign-in form, where they enter their email and password. That form looks like Fours' standard one unless you brand it as well, with the **Auth0 Universal Login logo** card near the bottom of the tab. 1. Paste the address of your logo image into the card's field, for example `https://example.com/logo.png`. Use an address anyone can open: the sign-in form loads the logo straight from it, not from the logo you uploaded in [Brand Settings](/prm/brand-settings/). 2. Click **Sync to Auth0**. Fours confirms with *"Synced to Auth0 Universal Login."* The sync puts that logo and your brand primary color on the sign-in form, and turns on sign-in with Google, Microsoft, and email and password for your partners. Once it's done, the card shows that your portal is linked to an Auth0 Organization. - **It takes effect straight away.** It's separate from **Save Login Page Settings**, which neither saves nor undoes it. - **Your brand color is copied at the moment you sync.** If you change it in Brand Settings later, click **Sync to Auth0** again. - **It needs Enable Custom Login Page on.** Only your branded login page sends partners to the branded sign-in form. :::warning If your organization signs in to Fours through its own enterprise single sign-on, the sync doesn't turn on Google, Microsoft, or email and password, and if you set up enterprise single sign-on later, Fours turns them off again the next time **Settings → SSO** loads. The sign-in form then offers your partners only your organization's own single sign-on. ::: ### Save your settings Click **Save Login Page Settings** to apply your changes. ![Partner Portal login page settings with branding, login URL, HTML snippet, and background image options](images/set-up-your-partner-portal-login-page-2.png) ## What Partners See When They Sign In With **Enable Custom Login Page** on, your login page asks a partner for their work email before anything else. There are no separate Log In and Sign Up buttons to choose between: Fours checks the address and shows the partner the next step for them. 1. The partner enters their **Work email** and clicks **Continue**. 2. Fours checks the address against your partnerships and shows one of the screens below. Each one repeats the address the partner typed, so a typo is easy to spot, and each has **Use a different email** to go back. 3. If the partner goes on to **Log In** or **Create your account**, their address is already filled in on the next screen. | When the work email is… | The partner sees | What they can do | | --- | --- | --- | | On your own company's email domain | **That is a {your company} address** | Nothing on this page. A company can't be its own partner, so your team uses the Fours Console instead. | | From a personal email provider, such as Gmail | **Use your work email** | Go back and enter a work address. Fours matches companies by email domain, so a personal address can't be linked to a partnership. | | At a company whose Fours organization is linked to an **Active** partnership with you, and the person already has a Fours account | **Welcome back to {your company}** | **Log In** | | At a company whose Fours organization is linked to an **Active** partnership with you, but the person has no Fours account yet | **{your company} already partners with your company** | **Create your account** | | At a company that isn't your partner, whose domain belongs to more than one Fours organization | **Your company has more than one Fours account** | Log in to the Fours Console instead. Fours doesn't guess which organization they belong to. | | At any other company | **Your company has not partnered with {your company} yet** | **Apply to be a partner**, which opens your [default application form](/prm/partner-registration-form/#choose-your-default-application-form). | Only an **Active** partnership counts. People at a company you've invited that hasn't accepted yet are treated as not partnered, so the invitation email you sent them is their way in. The partnership also has to be linked to the company's Fours organization: Fours looks for the organization on the domain of the address the partner typed. An **Active** partner record that isn't linked to a Fours organization is treated as not partnered too, so its people see **Your company has not partnered with {your company} yet**. Before a partner types anything, the page also shows a **New to {your company}?** card with a **Sign up to be a partner** button, for companies that haven't partnered with you yet. It opens the same default application form. If Fours can't find a default application form for your organization, the card doesn't appear, and a partner in the last row of the table sees *"Applications are not open through this page right now."* instead of the button. To stop the page being used to look up addresses in bulk, Fours limits how many addresses can be checked from one IP address in a short time. Someone who checks too many in a row sees *"Too many attempts. Wait a few seconds and try again."* ```d2 direction: down email: "Partner enters a work email\nand clicks Continue" { shape: rectangle } own: "Your own company's\nemail domain?" { shape: diamond } personal: "Personal email\nprovider?" { shape: diamond } active: "Active partnership linked to\nthat company's Fours organization?" { shape: diamond } account: "Has a Fours\naccount?" { shape: diamond } several: "Domain has more than one\nFours organization?" { shape: diamond } console: "Your own address\nuse the Fours Console" { shape: rectangle } workemail: "Use your work email" { shape: rectangle } login: "Welcome back\nLog In" { shape: rectangle } signup: "Already partners\nCreate your account" { shape: rectangle } multi: "More than one Fours account\nuse the Fours Console" { shape: rectangle } apply: "Not partnered yet\nApply to be a partner" { shape: rectangle } email -> own own -> console: "yes" own -> personal: "no" personal -> workemail: "yes" personal -> active: "no" active -> account: "yes" account -> login: "yes" account -> signup: "no" active -> several: "no" several -> multi: "yes" several -> apply: "no" ``` --- Source: https://doc.fours.com/prm/partner-registration-form/ # Partner Registration Form Instead of inviting partners one by one, let prospective partners apply through a registration form on your website. Fours builds and hosts the form for you, then gives you a unique link and embeddable code so you can publish it wherever you'd like. --- ## Overview A partner registration form is a hosted signup form that prospective partners can fill out to apply to your partner program. Fours provides each form with its own URL and an embed snippet, so you can share it as a direct link or place it directly on a page of your website. :::info You need an **Admin** or **Editor** role to create or edit registration forms. If the fields appear locked or read-only, check your role with your Fours admin. See [Account](/get-started/account/) for managing users and roles. ::: ## Create a Partner Signup Form :::warning Registration forms can't be deleted after they're created — only edited. ::: 1. **Access Sign Up Forms in Settings** 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Sign Up Forms**. 3. Click **+ Create Form**. ![Create Form button under Partner Sign Up Forms settings](images/create-a-partner-registration-form-and-e-1.png) 2. **Create the form** 1. **Form Name**: Appears as the heading partners see at the top of the form, so name it with them in mind (for example, "Apply to Partner w/ Fours"). 2. **Description**: A short note about what the form is for. 3. **URL Slug**: Automatically generated as part of the form URL and can't be edited. 4. **Welcome Message**: Message shown at the top of the form. Use it to explain what applicants can expect after submitting. 5. **Submit Button Text**: Label displayed on the form's submit button. The default is **Submit Application**, but you can customize it. ![Form creation panel with name, description, welcome message, and submit button fields](images/create-a-partner-registration-form-and-e-2.png) 3. **Review the required fields** Every registration form includes the following required fields, which can't be removed or reordered: * First Name * Last Name * Work Email * Company Name * Company Website * Why do you want to partner with us? 4. **Add custom fields (optional)** 1. To collect additional information, click **+ Add Field**. 2. Drag and drop fields to change the order in which partners see them. ![Adding and reordering custom fields on the form](images/create-a-partner-registration-form-and-e-3.png) 5. Click **Create Form** to save. ## Share and Manage Your Registration Forms After you create a form, it appears under **All Forms** with its own unique URL. From the **Actions** column, you can: ![Actions column options for a form under All Forms](images/create-a-partner-registration-form-and-e-4.png) 1. **Copy link** — Copies the form's direct URL to your clipboard, ready to share with a prospective partner. 2. **Open** — Opens the live form in a new tab, useful for previewing exactly what a partner would see. 3. **Edit** (pencil icon) — Go back and change the form's fields, welcome message, or other settings. 4. **Copy embed code** (`` icon) — Copies a ready-to-use embed snippet to your clipboard, for placing the form directly on a page of your website. 5. **View details** (document icon) — Opens a technical details panel showing the form's underlying field structure in raw format. ## Choose Your Default Application Form Every selling organization with Partner Management has a form called **Partner Sign Up**. Fours adds it alongside any forms you've built yourself, with just the six required fields listed above, and you can edit or rename it like any other form. One of your forms is always the **default application form**. It starts as **Partner Sign Up**. To choose another: 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Sign Up Forms**. 3. In the **Default application form** card at the top, pick a form from the list. Fours saves the choice straight away and confirms with *"Default application form updated"*. The list has no empty option, because there is always a default. The default is the form a company reaches from **Apply to be a partner** on your [public deal registration link](/prm/public-deal-registration-link/), when that link only takes deals from connected partners. It is also where **Sign up to be a partner** and **Apply to be a partner** lead on your [branded partner login page](/prm/partner-portal-login-page/#what-partners-see-when-they-sign-in). ## Embed the Form on Your Website If you'd like the registration form to appear directly on a page of your website instead of opening in a separate page, embed it using the code Fours generates. Before embedding works, you must allow the domains where the form will appear. 1. Under **Allowed embed domains**, enter each website domain that can embed your forms, one per line (for example, `https://partners.example.com`). 2. Click **Save Domains**. ![Allowed embed domains configuration with Save Domains button](images/create-a-partner-registration-form-and-e-5.png) 3. Go back to the **All Forms** section, then click **Copy embed code** (``) for the form you want to embed. 4. Paste the copied code into your website where you'd like the form to appear. :::info The allowlist applies to all of your registration forms. If no domains are configured, embedded forms won't load — but the direct form URL will continue to work. It is also the allowlist for your [public deal registration link](/prm/public-deal-registration-link/#embed-the-form-on-your-site). **Partners → Settings → Co-Sell** edits the same list, so a change made on either screen applies to both, and whichever saves last wins. ::: ## Review Applications Each submission appears under **Partners → Applications** as **Pending**. It stays Pending until you approve or decline it, or until it expires 15 days after it was submitted. From then on it can't be approved or declined, and a daily check marks it **Expired**. Approved, declined, and expired applications stay in the list, so you can always see who you turned down. See [Track Partner Collaborations](/prm/collaborations/#review-partner-applications) for how to read what an applicant submitted, and how to approve or decline. Two emails can go out when someone applies: **Partner application received**, to your team, and **Partner application confirmation (to applicant)**, to the person who applied. Whether each one is sent is controlled under **Settings → Notification**. See [Email Notification](/settings/email-notification/). ### Work Email Required The **Work Email** field identifies the applicant's company, so the form doesn't take an application from a personal email provider, such as Gmail or Outlook. Fours uses the same list of personal email domains as the [invite wizard](/prm/invite-partners/#step-2-purpose). The applicant sees *"Please apply with your work email address. Personal email addresses (such as Gmail or Outlook) can't be used for a partner application."* in the form, with their answers still filled in, so they can correct the address and submit again. Nothing is added to **Applications**. ### One Open Application per Company A company can have only one open request with you at a time. When someone submits a form, Fours takes the domain of their **Work Email** and checks for an open application or invitation with that company. If there is one, the form doesn't take the submission and nothing is added to **Applications**. The applicant sees a message in the form that names your company and when the earlier request was made: | The company already has… | The applicant is told | | --- | --- | | An application waiting for your decision | They've already applied and it's being reviewed, so there's no need to apply again, and to contact you directly if they've heard nothing back. | | An invitation from you that hasn't been answered | You've already sent their company an invitation, so they should open that email to accept it — or check their spam folder, or ask their contact at your company to resend it. | | A deal registration from your [public deal registration link](/prm/public-deal-registration-link/) waiting for your review | They registered a deal that's still being reviewed, and accepting it sets up the partnership, so there's no need to apply separately. | Only an open request counts: one you've declined, one that was cancelled, or one that has expired doesn't stop the company applying again. The same rule stops you inviting a company that has an open application. See [One Open Invitation per Company](/prm/invite-partners/#one-open-invitation-per-company). --- Source: https://doc.fours.com/prm/commission-plans/ # Set Up and Manage Commission Plans Commission settings control how much partners earn and under what terms — a referral fee, a reseller margin, a co-sell split, or a finder's fee. --- ## Overview Fours gives you two layers to work with: - **Standard Defaults** apply automatically to all partners. - **Custom Plans** override those defaults for specific partners who need different terms. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## How Commission Plans Are Applied When a co-sell is created, its **Revenue Share** tab is populated using the following priority order: **`Custom Plan → Standard Defaults → Manual`** Fours first checks whether the partner has an assigned Custom Plan. If not, it uses your Standard Defaults. If no applicable defaults are available, the revenue share setup falls back to a manual configuration path rather than being automatically populated. ## The Four Commission Types Both Standard Defaults and Custom Plans are organized around the same four commission types: | Type | Purpose | | --- | --- | | Referral Fee | Pays a partner for referring an opportunity to you. | | Reseller Margin | Pays a partner that resells your product directly. | | Co-Sell Revenue Split | Shares revenue on opportunities you and the partner close together. | | Finder's Fee | Pays a partner for introducing an opportunity with limited involvement beyond the introduction. | You'll set the same fields below for whichever commission types apply to your partner program. ## Understand the Fields Both Standard Defaults and Custom Plans use the same set of fields for every commission type. | Field | Description | | --- | --- | | Revenue Share Model | Determines how the commission is calculated.
**% of Final Transaction**: Pays the partner a percentage of the deal value. Use this when commission should scale with deal size.
**Fixed Amount**: Pays the partner a flat amount regardless of deal value. Useful for programs that pay the same amount for every qualified lead or referral. | | Default Rate (%) | Percentage used when the model is % of Final Transaction. For example, a 15% rate on a $100,000 deal results in a $15,000 commission. | | Payment Trigger | Determines when the commission becomes payable.
**On Deal Close**: Commission becomes payable as soon as the deal is marked Won.
**On Customer Invoice**: Commission becomes payable after the customer has been invoiced.
**On Payment Received**: Commission becomes payable only after customer payment has been received. | | Clawback Window (days) | Optional number of days during which a paid commission can still be reversed if the deal is canceled or otherwise reversed. | | Maximum Commission Cap | Optional maximum payout regardless of deal size. | | Minimum Deal Value | Optional minimum deal amount required before any commission is paid. | | Renewal Commission | Controls whether commission is paid only on the initial deal (One-time) or also on renewals (Recurring). | ## Set Your Standard Commission Defaults The **Standard Defaults** tab is selected by default when you open the **Commissions** page. These values become your global commission rules and apply to all partners unless a Custom Plan overrides them. 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Commissions**. 3. Open the **Standard Defaults** tab (selected by default). ![Standard Defaults tab on the Commissions page](images/set-up-and-manage-commission-plans-1.png) 4. For each commission type your program actually uses, fill in the fields as described above in the [Understand the Fields](#understand-the-fields) section. 5. Click **Save Defaults**. ## Create a Custom Commission Plan Use this when a specific partner needs different terms than your defaults — for example, they negotiated a higher margin, or a strategic account gets better payment terms. 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Commissions**. 3. Click the **Custom Plans** tab, then **+ New Plan**. ![Custom Plans tab with the New Plan button](images/set-up-and-manage-commission-plans-2.png) 4. Give the plan a **Plan name** and an optional internal **Description** (not partner-facing). 5. For each commission type, check the box to enable it for this plan, then fill in its fields the same way as Standard Defaults. ![Custom plan editor with commission types to enable](images/set-up-and-manage-commission-plans-3.png) 6. Click **Create Plan**. :::tip Any type you leave unchecked falls back to your Standard Defaults — it doesn't default to zero. ::: ## Assign a Custom Plan to a Partner Creating a plan doesn't apply it to anyone. A custom plan sits unused until you attach it to a specific partner, and you do that from the partner's own record rather than from the Commissions page. 1. Go to **Fours Console**, then **Partners**. 2. In **All Partners**, click the partner you want to put on the plan. 3. In the right-hand sidebar, find the **Commercial** card. The **Commission Plan** row shows which plan applies today — **Default** when none has been assigned. 4. Click **Assign plan**. 5. In the **Assign Commission Plan** dialog, open the **Plan** dropdown and choose one: - **Default (Standard Defaults)** — remove any custom plan and fall back to your organization-wide defaults. - Any **Active** custom plan, listed by name. Plans you haven't activated don't appear here. 6. Click **Confirm**. ![The Assign Commission Plan dialog — the plan selector, with the reminder that the change applies to future co-sells only and leaves existing ones untouched](images/47-assign-commission-plan.png) :::info Assigning a plan applies to **future co-sells only**. Co-sells that already exist keep the terms they resolved with when they were created — changing a partner's plan never rewrites a deal you already agreed. ::: :::tip Don't see the **Commercial** card or the **Assign plan** link? Commission features are enabled per organization. If the card is missing entirely, check with your Fours admin. ::: ## See What a Partner Owes and Is Owed A partner record has its own **Commissions** section that reports the relationship in both directions rather than as one blended number: - **You owe** — pending commission you owe that partner. - **{Partner} owes** — pending commission the partner owes you. - **Paid so far** — what has already settled. When money moves both ways, this splits into a paid-by-you figure and a paid-by-them figure. The table underneath filters by **Type**, **Direction** (`You pay` / `You receive`), and **Currency**, with tabs for **All**, **Pending**, and **Completed**. For how to read and work that section, see [Work a Partner Record](/prm/work-a-partner-record/). ## Commission Values on a Fours Co-Sell The commission types above are the labels you configure your program with. When a commission is attached to a **Fours co-sell**, the record stores one value from each of these two fixed sets — and these are the exact strings the bulk import below expects. **Commission type** | Value | Meaning | | --- | --- | | `Referral Fee` | Paid for referring the opportunity. | | `Reseller Margin` | The margin a reselling partner keeps. | | `Cosell Split` | A revenue split on a jointly closed deal. | | `Finder Fee` | Paid for the introduction alone. | **Payment trigger** | Value | Commission becomes payable | | --- | --- | | `On Close` | When the deal is marked Won. | | `On Invoice` | Once the customer has been invoiced. | | `On Payment` | Only after the customer pays. | | `Custom` | On terms agreed for that specific deal. | ## Import Historical Co-Sell Referrals Deals that closed before you started tracking them in Fours can be loaded in bulk, so your commission history is complete rather than starting from the day you switched on. This lives with your co-sell settings, not on the Commissions page. 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Co-Sell**. 3. Under **Bulk import historical referrals**, click **Upload CSV**. 4. Click **Download Template** to get a file with the correct headers, then fill in one row per deal. 5. Drag the finished file onto the drop area, or click **Choose CSV File**. 6. Review the preview table. Rows with problems are flagged; remove any you don't want with the **trash** icon. 7. Click through to submit. Fours confirms how many rows were queued. ![Settings → Partner → Co-Sell — the Auto-accept referrals toggle above the Bulk import historical referrals block and its Upload CSV button](images/46-bulk-import-cosell.png) **Required columns** are **Partnership ID**, **Opportunity Name**, **Stage**, and **Customer Company**. The template also carries Opportunity Type, Deal Role, customer website / industry / country, close date, deal value and currency, both sides' owner name and email, CRM opportunity ID, a brief, and a closed-lost reason. **The commission columns are optional.** When you use them: - **Commission Amount** is a flat amount in the deal's currency. If your arrangement was a percentage, work out the figure yourself first — there is no separate commission currency column, because the commission always rides the deal currency. - **Commission Type** and **Payment Trigger** take the values listed in [Commission Values on a Fours Co-Sell](#commission-values-on-a-fours-co-sell) above. - **Commission Status** marks a won deal's commission as already settled. Leave it blank and the commission rests as pending. :::info Imported records are created **silently at the stage you give them** — including `Won` and `Lost`. No partner notifications are sent, which is the point: you're recording history, not opening a conversation about a deal that finished months ago. The import runs in the background. Submitting confirms and closes the dialog rather than reporting per-row results; the outcome of each row shows up afterward in **Cosell → Metrics → Logs**. ::: :::tip The same **Partners → Settings → Co-Sell** section holds **Auto-accept referrals** — an organization-level switch that accepts inbound Fours referrals from partners you nominate, stamping a default owner on each one. It is unrelated to the import, but it is the other thing on this page. ::: ## The Commission Lifecycle After Close-Won The plan decides *what* a partner is owed. Once the deal is Won, the commission moves through a fixed sequence that records *whether it has actually been paid* — and each step belongs to one side of the deal, so neither party can advance the other's half. ```d2 direction: right classes: { s: { style.border-radius: 8; width: 170 } } pending: "PENDING" { class: s } approved: "APPROVED" { class: s } sent: "PAYMENT_SENT" { class: s } confirmed: "CONFIRMED" { class: s } clawed: "CLAWED_BACK" { class: s } proposal: "PENDING_UPDATE_APPROVAL\n(terms change in flight)" { class: s; style.stroke-dash: 3 } pending -> approved: "seller approves" approved -> sent: "seller marks payment sent" sent -> confirmed: "partner confirms receipt" sent -> approved: "partner rejects payment\n(recorded as PAYMENT_REJECTED)" confirmed -> clawed: "seller claws back\n(clawback window only)" pending -> proposal: "seller proposes\nnew terms" approved -> proposal: "seller proposes\nnew terms" proposal -> pending: "partner approves\nor rejects" proposal -> approved: "partner approves\nor rejects" ``` | Transition | Who does it | What it means | |---|---|---| | `PENDING` → `APPROVED` | Seller | The seller accepts the calculated commission as owed. | | `APPROVED` → `PAYMENT_SENT` | Seller | Payment has been issued outside Fours; the ledger records it. | | `PAYMENT_SENT` → `CONFIRMED` | Partner | The partner confirms the money arrived. This is what closes the loop. | | `PAYMENT_SENT` → `APPROVED` | Partner | The partner says the payment did not arrive. Fours records `PAYMENT_REJECTED` and returns the commission to `APPROVED` so the seller can re-send. | | `CONFIRMED` → `CLAWED_BACK` | Seller | The deal reversed inside the clawback window, so the commission is reversed too. Only possible after the partner confirmed, and only while the window is open. | **Changing the terms after Close-Won is a separate, two-sided flow.** The seller proposes new revenue-share terms; the commission moves to `PENDING_UPDATE_APPROVAL` and waits for the partner to approve or reject, which returns it to whichever state it was in before. A seller cannot quietly re-rate a won deal. :::info Working through the API? These are exactly the transitions [Apply a commission lifecycle action](/api/update-commission-lifecycle/) accepts — you send the target `state`, and the matching action is derived from the pair. Proposing new terms is [Propose a post-Won commission-terms update](/api/propose-commission-update/). Any other pair is rejected. ::: ## Where This Shows Up on a Deal Once a co-sell is created, its **Revenue Share** tab shows the resolved terms — the model, rate, payment trigger, and clawback window that apply — based on the priority order above. ![Revenue Share tab on a co-sell showing resolved commission terms](images/set-up-and-manage-commission-plans-4.png) --- Source: https://doc.fours.com/prm/partner-tiers/ # Partner Tiers Create levels within your partner program so you can recognize partners differently based on their engagement or success. --- ## Overview **Partner Tiers** let you build a structure like Registered → Silver → Gold → Platinum. Each partner belongs to one tier at a time, and their assigned tier is visible to both you and the partner. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Create a Tier 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Tiers**. 3. Click **+ New Tier**. ![New Tier button on the Partner Tiers settings page](images/set-up-and-manage-partner-tiers-1.png) 4. Fill in the tier details: - **Name** — What the tier is called, for example "Gold." This shows to partners. - **Badge color** — The color used for this tier's badge wherever it appears, including on the partner's own view of their status. - **Description** — Shown directly to partners in their portal. Use this to explain what the tier represents and what it took to get there, for example: "_Advanced Partners have a dedicated practice built around our platform, backed by a track record of successful customer outcomes._" - **Benefits** — A list of what the tier actually unlocks, for example "Higher commission · MDF eligible · QBR." This is also partner-facing, so write it as something a partner would want to read, not just an internal note. - **Default tier** — Toggle this on for the one tier new partners should automatically start at. Only one tier can be marked default at a time. ![Tier creation form with name, badge color, description, benefits, and default tier fields](images/set-up-and-manage-partner-tiers-2.png) 5. Click **Save tier** when you're done. ## Reorder Tiers Back on the main Tiers page, drag tiers using the grip handle on the left to set their rank from lowest to highest. This ranking is what determines which tier is "above" or "below" another, for example whether Gold outranks Silver. You can create **up to 6 tiers** total. ![Tiers list with drag handles for reordering](images/set-up-and-manage-partner-tiers-3.png) ## Edit or Delete a Tier 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Tiers**. 3. Click **Edit** (pencil icon) or **Delete** (trash icon) on the tier you want to change. ![Edit and delete icons on a tier row](images/set-up-and-manage-partner-tiers-4.png) ## Assign a Tier to a Partner Tiers aren't just definitions — they need to be assigned to actual partners. To change a partner's tier: 1. Go to **Fours Console**, then **Partners**. 2. Click the partner's name from **All Partners**. ![All Partners list with partner names](images/set-up-and-manage-partner-tiers-5.png) 3. On their **Overview** page, find the **Tier** card in the right sidebar. 4. Use the dropdown under "Their tier in your program" to select a different tier. ![Tier card in the partner Overview sidebar with a tier dropdown](images/set-up-and-manage-partner-tiers-6.png) The card updates immediately to show that tier's description and benefits, pulled directly from what you configured. :::tip You can also see and filter by tier from the **All Partners** list, using the Tier column and filter — useful for finding everyone at a given level at a glance. ::: --- Source: https://doc.fours.com/prm/file-sharing-defaults/ # Set Your File Sharing Defaults Define who can access each file category by default, so every new file you upload to Partner Files starts with the right sharing setting automatically. --- ## Overview **File Sharing Defaults** let you configure sharing once per file category instead of choosing a setting for every upload. When someone adds a new file to Partner Files, the file inherits the default sharing setting for its category. :::info You'll need an Admin or Editor role to change these settings. If the fields appear locked or read-only, check your role with your Fours admin. See [Account](/get-started/account/). ::: ## Set a Default per Category 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **File Sharing Defaults**. 3. Click the dropdown next to the category name. It shows the current setting, for example "Private". 4. Choose one of the three options: - **Private** — Only your team can see files in this category. Nothing is shared with partners by default. - **Auto-share with all partners** — Files in this category are automatically visible to your entire partner network the moment they're uploaded. - **Share with specific partners** — Files aren't shared broadly. You choose which individual partners get access. 5. Repeat for each category you want to change. 6. Once you've updated everything, click **Save Defaults**. ![File Sharing Defaults settings with a sharing dropdown open for a category](images/set-your-file-sharing-defaults-1.png) ## How Defaults Apply When You Upload a File Once your defaults are configured, every new upload follows the same flow: 1. Select a **Category** for the file. 2. The **Sharing** field automatically pre-fills with that category's default setting. ![File upload dialog with the Sharing field pre-filled from the category default](images/set-your-file-sharing-defaults-2.png) 3. If needed, change the sharing setting for that individual file before saving. :::tip The category default is only a starting point. Changing the sharing setting for one file does not affect the default for future uploads. ::: ## Who Can Change a Shared File Sharing grants **read and download only**. The organization that uploaded a file keeps control of it for its whole life. | Action | Owning organization | Organization the file is shared with | | --- | --- | --- | | View and download | Yes | Yes | | Rename | Yes | No | | Change who it's shared with | Yes | No | | Delete | Yes | No | The **Actions** kebab menu on a row still shows **Edit** and **Delete** to everyone who can see the file. On a file you don't own, choosing either one is refused by Fours and nothing changes — the check runs on the server, not in the table. :::info This cuts both ways. A partner who shares a file with you keeps the same control over their file that you keep over yours. If a shared file needs a new name or a different audience, ask the organization that uploaded it. ::: ## Who You Can Share With You can only share a file with an organization that is an **active** partner of yours. - **Inactive**, **suggested**, and **pending** partners are rejected. - The partnership counts in either direction, so the partner does not need a matching partnership record of their own. - A partner company that isn't a Fours organization has no organization to address, so it can't be named as a share target. Sharing is all or nothing. If you select several organizations and one of them isn't an active partner, the whole share is refused rather than going through for the rest — Fours names the organizations it rejected so you can remove them and try again. :::tip If a share fails and the organization looks right, check its status in **All Partners** first. An invitation that hasn't been accepted yet leaves the partner `PENDING`, which is not shareable. ::: --- Source: https://doc.fours.com/prm/add-portal-users/ # Add Portal Users Give your teammates access to the Partner Portal: automatically through single sign-on, by letting them join on their own, or by adding them yourself. --- ## Overview Your teammates can get into the Partner Portal three ways: automatically through single sign-on (SSO), by asking to join your partner organization, or by being added by you. Which one applies depends on whether your company's email domain is already connected to Fours. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Sign in with single sign-on (SSO) If your teammate's email matches your company's domain, they can sign in to the Partner Portal directly using your company's single sign-on (SSO). Fours recognizes the domain automatically, so no invite is required. ## Let teammates join on their own A teammate who signs up to Fours with an address on your company's email domain, and isn't in any organization yet, is taken to **Join an Organization**. It lists the Fours organizations on their email domain, including yours. 1. Next to your organization, the teammate clicks **Join**. 2. They choose a **Requested Role** — **Viewer**, **Editor**, or **Admin** — and write a short **Message**, between 10 and 1,000 characters. 3. They click **Submit Request**. Because yours is a partner organization, nobody normally has to approve the request. Fours adds the teammate straight away, tells them *"You have joined the organization."*, and **Go to Home** takes them in. Fours also emails them that the request was approved. If Fours can't add them automatically, the request stays **Pending** instead and waits like any other join request: the teammate is told their request was submitted, and your organization's Admins are emailed to approve it under **Users & Roles**. - **A request for Admin is approved automatically as Editor.** Nobody reviews an automatic approval, so an address on your domain can't be used to give someone user management. A request that stays **Pending** is reviewed by an Admin, who chooses the role to grant. - **Nobody on your side is notified when a request is approved automatically.** Check **Users & Roles** to see who has joined. - **Only partner organizations work this way.** A request to join a seller organization, including one that is also someone's partner, waits for an admin there to approve it — see [Review Join Requests](/get-started/account/#review-join-requests). ## Add a teammate yourself 1. Go to **Partner Portal**, then click your profile icon in the top-right corner. ![Profile icon in the top-right corner of the Partner Portal](images/add-users-to-your-partner-portal-1.png) 2. Click **Settings**. ![Settings option in the profile menu](images/add-users-to-your-partner-portal-2.png) 3. Go to **Users & Roles**, then click **+ New User**. ![Users & Roles page with the New User button](images/add-users-to-your-partner-portal-3.png) 4. Enter your teammate's **First Name**, **Last Name**, and **Email** — an address on your company's email domain — then pick their **Role**. ![New user form with name, email, and role fields](images/add-users-to-your-partner-portal-4.png) 5. Click **Save**. :::info Saving adds your teammate to your organization straight away, with the role you picked, and Fours emails them an invitation with a link to sign up. The link opens the sign-up form with their email address already filled in. If they had already asked to join your organization, Fours settles that request at the same time and tells you: *"This user already had a pending join request for this organization — it has been resolved automatically."* ::: For more details on user role types, see [Manage Users and Roles](/get-started/account/). --- Source: https://doc.fours.com/prm/sync-partners-from-salesforce/ # Sync Partners from Salesforce If your partner companies already exist in Salesforce, you don't have to re-enter them into Fours — pick which Salesforce accounts count as partners and they'll appear automatically in Partner Discovery, and optionally sync their documents into your file library. --- ## Overview Once Salesforce is connected, you can tell Fours which of your Salesforce accounts are partners. Fours uses a filter you define to match those accounts and surface them under **Partners → Partner Discovery → From Your CRM**. You can also turn on Document Sync to pull files from your partner records into your Fours file library. :::info This guide assumes Salesforce is already connected to Fours. If you haven't integrated yet, see [Salesforce](/integrations/salesforce/). Partner discovery and document sync currently support Salesforce only. ::: :::info You'll need an **Admin** or **Editor** role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Set Up Your Partner Mapping ### Step 1: Access your partner settings 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **CRM**. ![Partner CRM settings under Fours Console Settings](images/find-and-sync-partners-from-salesforce-1.png) ### Step 2: Choose the object that stores your partners Under **Object type**, select the Salesforce object where your partner companies are stored. ![Selecting the Salesforce object type that stores partners](images/find-and-sync-partners-from-salesforce-2.png) ### Step 3: Set the filter that identifies a partner Most teams mark partner accounts using an existing Salesforce field rather than a dedicated "is this a partner" checkbox. This step tells Fours which field and value to look for, so it knows which accounts are partners and which are regular customers. ![Configuring the filter field and value that identifies a partner](images/find-and-sync-partners-from-salesforce-3.png) 1. Under **Filter field**, select the field your team uses to mark an account as a partner — for example, the Account object's **Type** field. 2. Under **Filter value (equals)**, select or enter the value that field holds on partner records. What this field looks like depends on how it's set up in your Salesforce org: - If it's a **picklist** (a fixed dropdown of options), Fours shows you the same dropdown, so you just select the matching value — for example **Partner** — with no risk of a typo. - If it's a **free-text field**, you'll need to type the value manually, and it must exactly match what's stored on the record. Confirm the correct spelling and case with whoever manages your Salesforce data. ### Step 4: Map the name and email fields 1. Under **Name field**, select the field that holds the partner's company name. 2. Under **Email field**, select the field that stores the email address you want Fours to use when inviting the partner. Depending on your Salesforce setup, this may be an Account field or a custom field. ![Mapping the partner name and email fields](images/find-and-sync-partners-from-salesforce-4.png) ### Step 5: Test and save 1. Click **Test configuration**. Fours shows how many accounts match and a sample of the results. 2. Check the **Sample matches** table to confirm company names and emails look correct. 3. Click **Save**. :::tip If no records match during testing, double-check that the filter field and filter value exactly match the values stored in Salesforce. ::: ### Step 6: Check where matched partners show up After you save the configuration, matching accounts appear under **Partners → Partner Discovery → From Your CRM**. See [Partner Discovery](/prm/partner-discovery/) to learn more about Partner Discovery. ![Matched partners appearing under Partner Discovery From Your CRM](images/find-and-sync-partners-from-salesforce-5.png) ## Set Up Automatic Document Sync **Document Sync** adds files from your Salesforce partner records into your Fours file library automatically. 1. Turn on the **Document Sync** toggle. 2. Under **File types**, choose which file types to sync (PDF, PPTX, DOCX, XLSX, and others). Leave this empty to sync every supported type. 3. Under **Name contains**, optionally enter text to only sync files whose name includes it — for example, `Agreement` to pull in only agreement-related documents. Leave this blank to skip this filter. 4. Click **Save document sync** to save your settings. 5. Click **Sync now** to immediately trigger a sync. ![Document Sync settings with file type and name filters](images/find-and-sync-partners-from-salesforce-6.png) Once files sync, they appear in **Partners → Partner Files**, alongside any manually uploaded files. Use the **All Sources** filter and select **From Salesforce** to view only synced files separately. --- Source: https://doc.fours.com/prm/register-a-deal/ # Register a Deal with a Partner Register a deal when a customer needs to buy through a partner instead of directly from you — for example, when a prospect requires purchasing through a specific reseller. --- ## Overview Registering a deal creates a Co-Sell record that both you and the partner can track, including customer details, collaboration requests, and revenue share terms. :::info This article covers the seller experience in the Fours Console. To learn how partners register deals, see [Submit a Deal Registration (Partner)](/prm/submit-a-deal-registration-partner/). ::: ## Step 1: Start a Deal Registration 1. Go to **Fours Console**, then **Partners**. 2. In **All Partners**, click the name of the partner you want to register the deal with. 3. Click **Register a Deal** in the top right corner of the partner's profile. ![Register a Deal button on a partner's profile](images/register-a-deal-with-a-partner-1.png) ## Step 2: Choose or Skip a CRM Opportunity The **Select an Opportunity** window lets you link the deal to an existing CRM opportunity before completing the registration form. 1. Choose **Salesforce** or **HubSpot**, depending on where the opportunity lives. 2. Search by opportunity name, ID, or account, or browse the list. Each result shows the current opportunity stage and deal value, when available. 3. Select an opportunity, then click **Continue**. ![Select an Opportunity window with CRM search results](images/register-a-deal-with-a-partner-2.png) When you select a CRM opportunity, Fours pre-fills parts of the registration form using information from that record, so you don't have to enter the same details twice. ### Skip and Enter Details Manually If the deal isn't in your CRM, or you don't use Salesforce or HubSpot, click **Skip - Enter Manually**. This opens the registration form with blank fields you'll need to complete. ![Registration form opened with blank fields after skipping CRM](images/register-a-deal-with-a-partner-3.png) ## Step 3: Complete the Share Co-Sell Form The form is split into five tabs: **Opportunity & Customer**, **Deal Details**, **Revenue Share**, **Partner Collaboration**, and **Contacts**. The number on each tab shows how many required fields still need to be completed. When a tab is complete, the number changes to a checkmark. You can move between tabs at any time using **Back** and **Next**. ![Share Co-Sell form with five tabs and required-field counts](images/register-a-deal-with-a-partner-4.png) ### Opportunity & Customer 1. Enter an **Opportunity Name**. This identifies the deal internally and to your partner. 2. Add a **CRM Opportunity ID** if you have one. This is an internal reference only; the partner never sees it. 3. Confirm the **Opportunity Type** and **Target Close Date**, especially if this data came from a linked CRM record. 4. Confirm or enter the **Customer Company**, **Customer Website**, **Industry**, and **Country**. This is the customer information your partner sees when deciding whether to accept. 5. Optionally, add the customer's **Street**, **City**, **State/Region**, and **Postal Code** if you want a fuller address on record. **Customer Website** is validated for shape, not just for being filled in. It needs at least two labels separated by a dot and an alphabetic top-level domain: | Entry | Accepted? | | --- | --- | | `acme.com` | Yes | | `www.acme.co.uk` | Yes | | `https://acme.com/about?x=1` | Yes — the scheme and path are stripped | | `n/a` | No | | `192.0.2.10` | No — an IP address is not a website | | `pat@acme.com` | No — that's an email address in the wrong field | A rejected entry shows **"Enter a valid website, e.g. acme.com"**. Fours checks the format only — it never resolves the domain — so a well-formed typo still passes. ### Deal Details 1. Write a **Partner Brief** (minimum 20 characters) describing the customer's core need and why this partner is the right fit. This is the main pitch your partner reads before accepting, so make it specific. 2. Optionally, add a **Use Case** — a short label for the customer's primary use case (for example, "Workload migration and expansion"). 3. Confirm the **Deal Value** and **Currency**. 4. Check off the **Transaction Model**: Cloud Marketplace, Reseller Agreement, Direct Partner Contract, or Other. You can select more than one. :::info Because you are registering as the **Seller**, **Deal Value** must be greater than 0 — it's the figure the partner's commission is calculated against, so a blank or zero value has nothing to pay out on. **Currency** is required whenever an amount is present. A partner registering as a **Referrer** is held to a looser rule: they may leave the value blank when they don't know it yet. See [Submit a Deal Registration (Partner)](/prm/submit-a-deal-registration-partner/). ::: ### Revenue Share This tab never pre-fills from your CRM, because commission settings are managed in Fours and in partner commission plans — not in Salesforce or HubSpot. 1. Set **Deal Value Visibility**. By default, **Show deal value** is selected, which lets partners see both the deal amount and their commission. This option is typically recommended for resellers and co-sell partners. 2. Choose a **Commission Type** first. This selection determines the commission settings available for the deal. Available options include: - Referral Fee - Reseller Margin - Co-Sell Revenue Split - Finder's Fee After you select a commission type, the **Commission Rules** panel appears. It shows the **Rate**, **Maximum Cap**, **Minimum Deal Value**, and **Renewal Commission** that apply to the partner. These values come from the partner's **Custom Plan** if one exists, otherwise from your organization's **Standard Defaults**. To learn more, see [Set Up and Manage Commission Plans](/prm/commission-plans/). 3. Confirm the **Revenue Share Model** and **Payment Trigger**. If a plan resolved automatically, these should already reflect it, but you can adjust them for this specific deal if it needs different terms than the plan default. 4. Optionally, set a **Clawback Window** in days. If the deal churns within this window after payment, the commission can be reversed. Leave it blank if you don't need a clawback. 5. Add any **Revenue Share Notes** for context. ### Partner Collaboration 1. Check off **What I Need From You**. At least one is required. 2. Optionally, add **Next Steps** (for example, "Schedule joint discovery call") and any **Notes for Partner**. ### Contacts - Your name and email are automatically filled in under **ISV Owner (Partner Manager)** based on your Fours account. You can optionally add a **Title** if you'd like the partner to see your role. - Click **Add contact** to include additional team members, such as another sales contact or account manager. - The **Partner Owner** section is blank when you create the deal. The partner provides their contact information after they accept the deal registration. ## Step 4: Submit and Track Your Deal Registration Once every tab shows a checkmark, click **Submit** on the **Contacts** tab. After you submit, the deal appears on the partner's profile under the **Co-Sell** tab, with a status of `Pending Acceptance` until the partner responds. --- Source: https://doc.fours.com/prm/track-and-respond-to-deals/ # Track and Respond to Deals Every deal registration, whether you submitted it to a partner or received it from one, appears in your Partner Co-Sells list, where you can track its progress, review its details, and respond to inbound registrations that need your approval. --- ## Overview The **Partner Co-Sells** list is where all of your deal registrations come together. From there you can: - Find and filter deals by direction and status. - Respond to inbound deals a partner has registered with you. - Track and manage an accepted or outbound deal as it moves through the pipeline. :::info For instructions on creating a new registration, see [Register a Deal with a Partner](/prm/register-a-deal/). ::: ## Find and Filter Your Deal Registrations 1. Go to **Fours Console**, then **Partners**. 2. Click **Partner Co-Sells**. 3. Use the **Direction** column to identify the type of deal: - **Outbound**: You registered the deal with a partner. - **Inbound**: A partner registered the deal with you. ![Partner Co-Sells list showing the Direction and Status columns](images/track-and-respond-to-partner-deal-regist-1.png) 4. Review the **Status** column to understand where the deal is in the process: - **`Pending Acceptance`**: An inbound deal waiting for you to accept or reject it. - **`Active`**: A deal that has already been accepted and is moving through the pipeline. :::tip Alternatively, open a partner's profile and select the **Co-Sell** tab to view only the deals shared with that partner. ::: ## Review Deal Registrations from Email When members of your team email in deal registrations, Fours turns them into drafts for you to review. Drafts collect in a panel above the **Partner Co-Sells** list, headed **N deal registrations from email**. The panel is hidden when there's nothing to review, and it starts collapsed so the list stays in view. 1. Go to **Fours Console**, then **Partners**, and click **Partner Co-Sells**. 2. Click **N deal registrations from email** to expand the panel. Each draft shows its **Name**, who it's **From**, the **Matched Partner** Fours suggests, and when it was **Received**, newest first. 3. Click a draft's name. The co-sell form opens, prefilled from the email, with a **Sent in by** line naming the teammate who sent it. 4. Under **Register with Partner**, keep the partner Fours matched, pick another, or choose **Create new partner…**. If the partner you pick has no confirmation contact on file, the form asks you to name the person there who should confirm the registration. 5. Review the rest of the form and submit it. Submitting registers the deal on the partner's behalf. Fours asks the partner's champion to confirm it, the same way **Register a Deal on Partner's Behalf** does on a partner record. See [Work a Partner Record](/prm/work-a-partner-record/). To throw a draft away, click its trash icon and confirm **Discard**. A discarded draft is removed permanently. :::info Drafts are only created from emails that members of your own organization send in. A partner can't create one by emailing Fours directly. ::: ### Open a Draft from Fours' Reply Fours replies on the email thread the registration came from, so the person who sent it in knows where it stands: - **Details needed** — Fours lists what's missing and asks for it on the thread. When nobody outside your organization is on the thread, the reply carries a **Complete in Fours →** button. - **Ready to confirm** — once Fours has what it needs, it sums up what it captured from the thread and carries a **Review & confirm in Fours →** button. If details are still missing after Fours has asked for them, the same reply is marked **Needs your input** and lists them. Everyone on the thread gets this reply, so a partner copied on it can reply to correct anything Fours captured. Either button opens the draft itself, whichever organization you last had open in Fours: - **If you're in the organization the draft belongs to**, Fours switches you into it and opens **Partner Co-Sells** with the drafts panel expanded and the draft's review form already open. If you're signed out, you sign in first. - **If you're one of that organization's partners**, Fours switches you into your own organization and opens your record of them, with a notice that they're reviewing the deal registration. It appears in your co-sells once they confirm it. - **Anyone else** sees *You don't have access to this deal registration*, with a **Go to your Fours home** button. If the draft has already been submitted or discarded, Fours says *"This deal registration is no longer pending review."* instead of opening it. If the draft can't be loaded, Fours says so and points you to the list. ```d2 shape: sequence_diagram teammate: "Your teammate" suger: Fours you: "You, in the seller organization" partner: "Partner copied on the thread" teammate -> suger: "Emails in a deal registration" suger -> teammate: "Reply on the thread:\nReview & confirm in Fours" { style.stroke-dash: 4 } suger -> partner: "The same reply, as a copy" { style.stroke-dash: 4 } you -> suger: "Click the button" suger -> you: "Partner Co-Sells with the\ndraft's review form open" { style.stroke-dash: 4 } partner -> suger: "Click the button" suger -> partner: "Their record of you, with a notice\nthat you're reviewing it" { style.stroke-dash: 4 } ``` ## Respond to an Inbound Deal When a partner registers a deal with you as the seller, it appears as an **`Inbound`** co-sell with a status of **`Pending Acceptance`**. :::info Deals registered through your [public deal registration link](/prm/public-deal-registration-link/) arrive here the same way. When one comes from a company that isn't your partner yet, accepting it also brings the company on as a partner, while rejecting it rejects only the deal. Before you accept such a deal, the **Accept & Complete Co-Sell** window warns that accepting also accepts your partnership with the company, and says whether its application is pending, declined, or expired. See [Decide a Held Registration](/prm/public-deal-registration-link/#decide-a-held-registration). ::: ### Step 1: Review the Deal Before Responding Open any pending deal to view its details. - A banner at the top explains the relationship between the partner and the opportunity, such as a partner referring a customer to your product. - The **Overview** section shows the opportunity type, target close date, the deal value estimated by the partner, and any notes they provided during registration. ![Inbound co-sell detail view with the banner and Overview section](images/track-and-respond-to-partner-deal-regist-2.png) ### Step 2: Accept or Reject the Deal #### Accept and complete the deal 1. Click **Accept & Complete** in the top-right corner to open the **Accept & Complete Co-Sell** window. ![Accept & Complete Co-Sell window](images/track-and-respond-to-partner-deal-regist-3.png) 2. Add at least one **Seller Deal Owner Contact**. Enter the contact's name, email address, and optionally their title. At least one contact is required. 3. Confirm the **Deal Value**. The partner's estimated amount carries over automatically, but you can update it and change the currency if needed. 4. Configure the **Commission Terms**: - Choose a **Commission Type**. This pulls the rate, cap, minimum, and renewal rules from the partner's Custom Plan if one exists, or your Standard Defaults if it doesn't (shown as "From Default settings" when no custom plan applies). - Confirm the **Revenue Share Model** and **Payment Trigger**. - Optionally, set a **Clawback Window** in days. - Set **Deal Value Visibility** — whether the partner sees the full deal amount and their commission. 5. Optionally, link the co-sell to a **Salesforce opportunity**, **HubSpot deal**, or **Dynamics 365 opportunity**. 6. Click **Accept**. :::info See [Set Up and Manage Commission Plans](/prm/commission-plans/) to learn how commission plans are configured. ::: #### Reject the deal registration Click **Reject** instead if the deal isn't a fit. This opens the **Reject co-sell** window. 1. Enter a **Reason** (for example, "Conflict with existing customer relationship"). This is required, and it's shown directly to the partner who registered the deal, so keep it factual and professional. 2. Click **Reject co-sell**. ![Reject co-sell window with the required Reason field](images/track-and-respond-to-partner-deal-regist-4.png) ## Act on a Co-Sell from Email Co-sell emails can carry a button that lets you act on the deal straight from your inbox. Each recipient gets a button of their own: | Button | When the email arrives | What the page asks for | | --- | --- | --- | | **Accept co-sell →** | A partner registers a deal with you. | The deal value and currency, plus the commission terms when commissions apply. | | **Mark Closed Won →** | The partner marks their copy of the deal Closed Won. | A deal value, but only if the deal doesn't have one yet. | | **Mark Closed Lost →** | The partner marks their copy of the deal Closed Lost. | A reason, which the partner reads. | How the buttons work: - **Each button is personal.** It was issued to one email address, works once, and expires after 24 hours. - **It needs an editing role.** The person clicking must have the **Admin** or **Editor** role in your organization. Otherwise the page shows **Sign In To Continue**, and they take the action in the console instead. - **The page shows who you're acting as.** When it needs nothing more, it records the action as soon as it opens. The action is recorded under your name, exactly as if you had clicked it in the console. Accepting this way makes you the deal owner on your side. - **Reject isn't offered from email.** To reject a registration, use **Reject** on the deal in the console. - **A link that no longer applies says so.** If it has expired, was already used, or the deal has moved on, the page tells you and points you to the console. ```d2 shape: sequence_diagram partner: Partner suger: Fours you: "You (Admin or Editor)" partner -> suger: "Registers a deal with you" suger -> you: "Email with your own Accept co-sell button" you -> suger: "Open the link within 24 hours" suger -> you: "Confirmation page: deal value, currency, commission terms" { style.stroke-dash: 4 } you -> suger: "Confirm" suger -> partner: "The co-sell is accepted" { style.stroke-dash: 4 } ``` :::info Emails that your co-sell and commission actions trigger, including actions taken from one of these buttons, can go out from your own connected Gmail. See [Send Co-Sell Emails from Your Gmail](/integrations/google-mail/#send-co-sell-emails-from-your-gmail). ::: ## Check Each Party's Status A deal you share with partners exists as one copy per organization: yours, and one for each partner. Each side closes its own copy, so your copy can read `Closed Lost` while a partner's reads `Closed Won`. The **Partners & Status** section on the deal lists every copy side by side, so you can see when the two sides disagree: - **Your organization comes first**, marked **You**, with the role **Seller** and your own copy's status. It has no **Shared** or **Accept Date**, because the deal was never shared with you. - **Then one row per partner**, with its attribution role (**Sourced**, **Influenced**, or **Transacted**), its status, the date the deal was **Shared** with it, and its **Accept Date**. The section appears once the deal has at least one partner. Partners see the same table from their side, with your row showing your status. ## Remove a Partner from an Accepted Deal A deal registration that has been accepted can still have a partner removed from it. The action is **seller-only**, sits on the partner's own row in **Partners & Status**, and is confirmed with **Remove & notify partner**. The removal is then recorded on the deal's **Activity** tab as **Partner removed: *{partner}***, marked **Removed**, so your side keeps a record of it. :::warning **Removal is total, not a soft "mark inactive".** The partner loses the deal entirely — it disappears from their portal, not just from your tab strip. ::: Three rules bound it, and the button is disabled with the reason when one applies: | Rule | Why | | ---- | --- | | **Not after the deal is won** | Removal is only possible while the outcome is still open. | | **Never leaves zero parties** | The last remaining partner cannot be removed. | | **Not once commission is committed** | Committed money is not unwound by removing someone from a record. | Because removal is only possible before the deal is won, any commission shown on that partner's tab is still a **projection** — so removing them destroys nothing already earned. ## Track and Manage an Active Deal Once a deal is accepted, or after you register an outbound deal, it moves through the same pipeline regardless of direction: **Pending** → **Active** → **In Discovery** → **Proposal Sent** → **Negotiating** → **Won** Two additional stages, **On Hold** and **Lost**, don't appear in the visual pipeline but can still be assigned manually when you change stages. ![Deal pipeline stages from Pending through Won](images/track-and-respond-to-partner-deal-regist-5.png) ## Link a CPPO to the Deal If a deal transacts through a CPPO with the partner, link that marketplace offer to the co-sell from the deal's **Marketplace connection** tab. On a deal you registered with a partner (**Outbound**), the tab shows: - **Linked CPPOs.** Each linked offer is a card with the offer's name, which opens the offer, the line **Linked CPPO · {marketplace}**, and the offer's current status. A cancelled, expired, failed, or otherwise dead offer shows its status in red. - **Suggestions.** When Fours finds a CPPO for this partner that isn't linked to any co-sell yet, it asks: *"A new CPPO was created for {customer}. Link it to this co-sell?"* Click **Link** to connect it, or **Dismiss** to hide the suggestion. Dismissals are remembered in your browser. - **A way forward when nothing is linked.** Once the partner has a cloud Account ID on file, the tab offers **Create CPPO**, which opens the CPPO form prefilled from the co-sell. Without one, it offers **Configure partner**, which opens the partner's record so you can add it under **Partner Details**. See [Work a Partner Record](/prm/work-a-partner-record/). An offer can be linked to only one co-sell, and a link can't be removed. If you try to link an offer that already belongs to another co-sell, Fours refuses and names that co-sell. On an **Inbound** deal, the tab only reads *"Awaiting ISV action — no marketplace offer is linked to this co-sell yet."* --- Source: https://doc.fours.com/prm/submit-a-deal-registration-partner/ # Submit a Deal Registration (Partner) Register a new deal in a partner's branded Fours PRM portal, add the collaboration details you need, and track the co-sell opportunity after you submit it. --- ## Overview When a partner or ISV invites you into their program, they give you access to a branded Fours PRM portal. From there you can register deals, request the support you need, and follow each opportunity as the partner reviews and accepts it in the Co-Sell area. If a seller has shared a public deal registration link with you instead, you can register a deal without a portal account. See [Register a Deal Through a Public Link](#register-a-deal-through-a-public-link). Before you begin, have the following ready: - Access to your partner PRM portal. - Basic customer and opportunity information. - The expected close date and estimated deal value. - Contact details for anyone who should be associated with the deal. ## Accept Your Partner Invitation Your invitation arrives as an email with a link. Opening it takes you to a public page — you don't need a Fours account yet, and there is no code to copy out of the email. The email may also link documents the sender wants you to read first, such as an NDA or a partner agreement. You can open them straight from the email, without a Fours account. The links work while the invitation is waiting for your answer and after you accept it. They stop working once you decline, or the invitation expires or is cancelled. ### Accept 1. Open the invitation link. The page is headed **Accept Partnership Invitation**, above the prompt *"Please share a brief response about your interest before confirming."* It does not name the inviting company — the link itself is the context, so keep the email that carried it if you need to check who it came from. 2. In the response box, write a short note about your interest. **This is required to accept** — the button won't submit without it. You have up to 4,000 characters, and a counter tracks what you've used. 3. Click **Accept Invitation**. 4. Fours records your response and asks you to confirm who you are: *"Please sign in to confirm your acceptance."* You're sent to the sign-in screen. 5. Sign in — or create your account — using **the same email address the invitation was sent to**. Matching that email is what proves the invitation is yours. Once you're signed in, Fours finishes the acceptance on its own and drops you into your new partner workspace. You don't click **Accept Invitation** a second time. ![The public Accept Partnership Invitation page — the heading and prompt above a response box with its 4,000-character counter, and a single full-width Accept Invitation button](images/50-accept-invitation.png) :::info Signing in with a different address than the one invited stops the acceptance and shows **Wrong Account**, naming the email the invitation was sent to. Click **Sign in with a different account** to switch, then let the acceptance finish. If something else goes wrong — a network drop, or a server that didn't answer — you get a **Try Again** button instead. Your response message is not lost. ::: ### Decline Declining never asks you to sign in. 1. Open the decline link from the same email. 2. Optionally add a note. Unlike accepting, this one is **not** required. 3. Click **Decline Invitation**. It submits immediately — there is no second confirmation — and Fours confirms with *"Thank you for letting us know."* ## Open the Partner PRM Portal Sign in to the branded Fours PRM portal provided by your partner or ISV. From the overview page, select **Register a Deal** to begin a new submission. - Confirm you're in the correct partner workspace. - Use the left navigation to reach **Co-Sell** later for tracking. ![Partner portal overview with the Register a Deal action](images/submit-a-deal-registration-partner-1.png) ## Complete the Registration Form The registration form opens as a guided workflow. Complete each section in order so the partner has enough information to review the opportunity. The form is organized into these sections: - Opportunity & Customer - Deal Details - Partner Collaboration - Contacts ![Deal registration form with the required sections across the top](images/submit-a-deal-registration-partner-2.png) ### Opportunity & Customer Enter the core customer and opportunity details. Required fields may vary by partner configuration, but this section usually captures who the customer is and what opportunity you're submitting. - Opportunity name and type - Target close date - Customer company and website - Industry and country - Optional CRM or internal reference ![Opportunity and customer information fields](images/submit-a-deal-registration-partner-3.png) **Customer website** is checked for shape before the form will submit. It needs at least two parts separated by a dot, ending in an alphabetic top-level domain: | Entry | Accepted? | | --- | --- | | `acme.com` | Yes | | `www.acme.co.uk` | Yes | | `https://acme.com/about` | Yes — the path is ignored | | `n/a` | No — no dot, no top-level domain | | `192.0.2.10` | No — an IP address is not a website | | `pat@acme.com` | No — that's an email address | Anything rejected shows **"Enter a valid website, e.g. acme.com"**. Fours checks the shape only; it does not visit the site, so a typo in a well-formed domain still gets through. ### Deal Details Add enough context for the partner to understand the opportunity and how the customer is expected to transact. - Explain why the customer needs the solution. - Add the estimated deal value. - Select the transaction model, such as Cloud Marketplace, Direct Partner Contract, or Other. ![Deal details, estimated value, and transaction model](images/submit-a-deal-registration-partner-4.png) Whether the **deal value** is mandatory depends on the deal role you picked: | Your deal role | Deal value | | --- | --- | | Referrer | Optional. Leave it blank when you don't know the number yet — a referral shouldn't be blocked on a figure you're guessing at. | | Seller | Required, and must be greater than 0. It's what the commission is calculated against. | Either way, a negative value is rejected, and any amount you do enter needs a currency alongside it. :::info Leaving the value blank as a Referrer has one consequence downstream: the partner can't auto-accept a referral that carries no deal value, so it waits for someone to review it by hand. Add an estimate if you want it to move faster. ::: ### Partner Collaboration Choose the support you need from the partner. This helps them understand how to engage and what next action to take. - Technical support, joint selling, commercial support, or solution design - Marketplace transaction support or product demo - Next steps and notes for the partner ![Partner collaboration options and next-step notes](images/submit-a-deal-registration-partner-5.png) ### Contacts and Submit Review the partner owner and add anyone else who should be connected to the deal. When the form is complete, select **Submit**. - Add a name, email, and title for each additional contact. - Include contacts who may need updates or follow-up. - Submitting notifies the partner or ISV for review. ![Contacts section with additional contact fields and Submit button](images/inline_18476e-82911_1.png) ## Track the Submitted Deal in Co-Sell After submission, return to the partner portal and open the **Co-Sell** tab. This is where submitted and shared opportunities are tracked. - Use Co-Sell to find submitted opportunities. - Monitor partner review and acceptance from the deal list. ![Co-Sell navigation in the partner portal](images/inline_18476e-82911_2.png) ### Review the Deal List The Co-Sell list shows a summary of each opportunity. Use it to quickly confirm status and spot deals that need attention. - Opportunity name, customer, stage, and target close date - Your deal role - Partner acceptance status, such as `Pending` or `Accepted` ![Co-Sell deal list with partner acceptance status](images/inline_18476e-82911_3.png) ### Open the Deal Details Select an opportunity to open the full deal record. The detail view shows the current stage, status, important dates, next steps, and customer information. - Review the current sharing status and partner acceptance. - Check the stage, target close date, deal value, and next steps. - In **Partners & Status**, see where each organization stands: the seller first (role **Seller**, with the seller's own status), then your organization (**You**), then any other partners on the deal. Each organization closes its own copy of the deal, so the seller's status can differ from yours. ![Deal detail view with status and stage tracking](images/inline_18476e-82911_4.png) ### Monitor Activity Use the **Activity** tab to keep track of collaboration history and communications related to the deal. - Review synced channels, email thread details, comments, and internal notes. - Use the activity history to understand what has happened since submission. ![Activity tab for communication and collaboration history](images/inline_18476e-82911_5.png) ### Revisit Collaboration and Deal Details The detail tabs make it easy to revisit information you submitted during registration, including collaboration needs and deal value. - Use the **Collaboration** tab to confirm the support you requested. - Use **Deal details** to review the value, model, and related fields. ![Collaboration and deal detail tabs inside the opportunity record](images/inline_18476e-82911_6.png) ## Register a Deal Through a Public Link Some sellers publish a public link for registering deals, on their website or in an email to you. It works without a Fours account and without signing in, whether or not your company is already their partner. 1. Open the link. The page is headed **Register a deal with *{seller}***. 2. Enter your **Work email**, then move to the next field. From the part after the `@`, Fours checks whether your company is already connected to the seller as a partner, and tells you what will happen to your deal: | You see | What it means | | --- | --- | | **Active partnership found with *{seller}*** | Your company is a connected partner. Your co-sell goes straight to the seller for review. | | **No active partnership with *{seller}* yet**, with *"We'll automatically send a collaboration request…"* | You can still register the deal. The seller receives a request to partner with your company alongside it, and reviews the two together. | | **No active partnership with *{seller}* yet**, with *"…accepts deal registrations from partners only"* | This link only takes deals from connected partners. There is no deal form and **Register deal** stays disabled. Use **Apply to be a partner** to apply to the seller's partner program, then register the deal once you're connected. | | **Couldn't check your partnership** | Check your work email and try again. A personal address, such as Gmail or Outlook, always ends up here: use your company's work email instead. | 3. Fill in the form. Fields marked with * are required. - **About you** — your name and **Work email***. - **The customer** — **Company name***, **Website***, **Industry*** (from a list), and **Country***. - **The deal** — **Deal name***; **Opportunity type***: `New Business`, `Renewal`, `Expansion`, or `Add-on`; **Target close date***, which must be in the future; **What problem is the customer solving?***, at least 20 characters; **Transaction model***: `Cloud Marketplace`, `Direct Partner Contract`, or `Other`, at least one; and an optional **Estimated deal value** with its **Currency**. You're registering as the Referrer, so leave the value blank if you don't know it yet. - **What do you need?** — **Partner needs***, at least one of Technical Support, Commercial Support, Solution Design, Joint Selling Support, Join a Customer Call, Transact via Marketplace, Post-Sales Support, Visibility Only, Product Demo, Training / Enablement, and Marketing Materials; plus **Anything else** you want the seller to know. 4. Click **Register deal**. The confirmation tells you where the deal went: - *"Thanks — your deal is registered and is awaiting the team's acceptance."* Your company is a connected partner, and the seller now reviews the deal like any other. - *"Thanks — your submission has gone to the team for review. They'll be in touch once they have looked at it."* The seller reviews your company and the deal together. If they accept the deal, your company becomes one of their partners. They may also approve your company's application first: your company then becomes their partner, Fours adds you to your company's Fours organization (creating one if needed), and your company gets its own copy of the deal, still waiting for the seller's acceptance. Other messages you may see: - *"Please register the deal with your work email address. Personal email addresses (such as Gmail or Outlook) can't identify your company."* — the email you entered is on a personal email provider. Change it to your company's work email and click **Register deal** again; the rest of the form stays filled in. - **Deal registration is closed** — the seller isn't taking registrations through this link right now. Reach out to your contact there; the link may reopen later. - **Page Not Available** — the link isn't valid, often because the seller changed it. Ask your contact for a new one. - A message that the form registers deals with partners — the email you entered is on the seller's own domain. Use your own company's work email. ## Act on a Co-Sell from Email Some co-sell emails carry a button that lets you act on the deal straight from your inbox: | Button | When the email arrives | What the page asks for | | --- | --- | --- | | **Accept co-sell →** | Your partner or ISV shares a co-sell with you. | Nothing, unless you're the seller on the deal. Then it asks for the deal value and currency, plus the commission terms when commissions apply. | | **Mark Closed Won →** | The other side marks the deal Closed Won. | Nothing, unless you're the seller and the deal has no value yet. Then it asks for one. | | **Mark Closed Lost →** | The other side marks the deal Closed Lost. | A reason, which the other side reads. | | **Approve commission change →** | The seller proposes new commission terms on a won deal. | Nothing. | How the buttons work: - **Each button is personal.** It was issued to your email address, works once, and expires after 24 hours. - **You need an editing role.** Your Fours user must have the **Admin** or **Editor** role in your organization. Otherwise the page shows **Sign In To Continue**, and you take the action in Fours instead. - **The page shows who you're acting as.** When it needs nothing more from you, it records the action as soon as it opens. The action is recorded under your name, as if you had taken it in the portal. Accepting this way makes you your side's deal owner. - **Declining isn't offered from email.** To decline a co-sell, open it in the portal. - **A link that no longer applies says so.** If it has expired, was already used, or the deal has moved on, the page tells you and points you to Fours. ```d2 direction: right trigger: "The other side shares the co-sell,\ncloses it, or proposes new terms" { shape: rectangle } email: "Fours emails you\nyour own button" { shape: rectangle } open: "You open it within 24 hours\nActing as: your name" { shape: rectangle } ask: "Anything to fill in?" { shape: diamond } form: "Enter the value, terms,\nor reason, then confirm" { shape: rectangle } record: "Recorded under your name" { shape: rectangle } trigger -> email -> open -> ask ask -> record: "no, recorded as the page opens" ask -> form: "yes" form -> record ``` ### When a Seller Registers a Deal from Email A seller's team can turn an email thread about a deal into a deal registration by forwarding it to Fours. If you're on that thread, you may get a copy of Fours' reply, with a **Review & confirm in Fours →** button. That button is for the seller. If you click it, Fours opens your record of that seller in your partner workspace, with the notice *"{seller} is reviewing this deal registration. It will appear in your co-sells once they confirm it."* The deal appears in your **Co-Sell** list once they confirm it. If anything Fours captured in the reply is wrong, reply to the email. --- Source: https://doc.fours.com/prm/invite-partners/ # Invite Partners Invite a single partner or bring in many at once from a CSV file, with Fours drafting the outreach email for you based on the purpose, tone, and context you provide. --- ## Overview You can invite partners into your network one at a time or in bulk using a CSV file. In either case, Fours can generate the outreach email for you from the purpose, tone, and context you supply — the more specific you are, the less editing you'll need afterward. :::info Sending an invitation requires a connected email account. If you haven't connected Gmail or Outlook yet, see [Connect Gmail to Fours](/integrations/google-mail/) or [Connect Microsoft Outlook to Fours](/integrations/microsoft-outlook/). ::: ## Invite a single partner The invitation wizard runs in four steps — **Choose**, **Purpose**, **Email**, and **Review** — listed across the top so you can always see where you are and move back with **Back**. ### Step 1: Choose 1. Go to **Fours Console**, then click **Partners**. 2. Click **+ Invite Partners**. The wizard opens on its **Choose** step. 3. Click **Single partner**. ![Invite Partners menu with the Single partner option](images/invite-partners-to-your-network-1.png) ### Step 2: Purpose On this step you choose who you're inviting, and then why. **If the partner is already known to Fours:** 1. Click **Select recommended partner**. 2. Use the **Select a partner** dropdown to choose their name. **If the partner is brand new:** 1. Click **Invite a new partner**. 2. Enter their company name under **Partner Company Name**. 3. Enter their contact under **Contact Email Address**. As you type the contact's email, Fours checks whether your organization already has an open invitation or application with that company. If it does, a notice appears under the field in place of the usual preview, and **Next** stays disabled. See [One Open Invitation per Company](#one-open-invitation-per-company). **A new partner needs a work email address.** Fours identifies a partner by its company's email domain, which a personal address can't provide. If the contact's email is on a personal email provider, a **Personal email address** panel appears in place of the preview — *"A partner is identified by their company's domain, which a personal address can't provide. Use your contact's work email instead."* — and **Next** stays disabled. Fours treats these domains as personal: `gmail.com`, `googlemail.com`, `yahoo.com`, `ymail.com`, `hotmail.com`, `outlook.com`, `live.com`, `msn.com`, `aol.com`, `icloud.com`, `me.com`, `mail.com`, `gmx.com`, `protonmail.com`, `proton.me`, `zoho.com`, `yandex.com`, and `qq.com`. Inviting a contact at a partner you pick with **Select recommended partner** isn't affected. :::info If Fours doesn't recognize the contact's email domain, it sends a standard invitation email with a link to join Fours and accept the partnership. The channel is automatically set to Direct. ::: Under **What's the purpose?**, select the option that matches this outreach: * **Network Invitation** — Formalize a partnership, with no specific deal yet. * **Account Overlap** — Explore mutual engagement or specific accounts. * **Deal Collaboration** — Collaborate on a specific, active opportunity. Then click **Next**. ![Partner selection and purpose options for a single invitation](images/invite-partners-to-your-network-2.png) ### Step 3: Email Context and tone are **fields on this step**, sitting next to the **Generate Email with AI** button they feed. They used to be two pages of their own; a single field occupying a whole page made it genuinely unclear whether what you typed reached the partner, and at least one customer skipped both pages and wrote the email by hand. Keeping them beside the button makes the connection obvious. 1. Describe why this partner is relevant under **What makes this partner relevant here?** — the more specific you are, the less editing you'll need afterward. 2. Pick a **tone** from the dropdown. Tone only seeds the generated draft, so it does not block **Next**. 3. (Optional) Link a document, such as your NDA or partner agreement, with **Insert file** under **Attach file link**. See [Link a file from the email](#link-a-file-from-the-email) below. 4. Click **Generate Email with AI** and wait a few seconds while Fours generates a subject and body. 5. Confirm the sending account under **Send From**. 6. Fill in **Recipient Email** and **Recipient Name**. 7. (Optional) Add anyone who should be copied under **CC**. 8. Review the generated **Subject** and **Email Body**, and edit either if needed. 9. Click **Next**. ![Generated invitation email with recipient and content fields](images/invite-partners-to-your-network-5.png) #### Link a file from the email A prospective partner may not have a Fours login yet, so an invitation can link documents they can read before they accept, without signing in. The **Attach file link** panel sits above **Generate Email with AI**, so the files you add go into the generated email too. 1. Under **Attach file link**, click **Insert file**. 2. In the **Insert file link** dialog, search or pick a category, then tick the files to link. 3. Click **Insert link**. With several files ticked, the button reads **Insert N links**. Each file appears as a chip under **Attach file link**. Fours also adds a sentence to the email body, such as *"Before we get started, you can review Partner NDA here:"*, followed by a `{{document:…}}` placeholder that becomes a link named after the file when the email is sent. You can move or reword the sentence. Keep the placeholder where you want the link. To unlink a file, remove its chip or delete that line. Generating the email with AI keeps your links. **Which files you can link** - Only **Partner Files** shared with **All Partners** that allow download. The dialog's **Sharing: All Partners** chip is fixed, and its **Not seeing a file?** note explains why: a new partner can't open **Private** or **Specific Partners** files. To link an NDA or agreement, add it to Partner Files and share it with all partners. - Up to **10** files per invitation. **What the recipient gets** - A link, not an attachment. It opens without signing in to Fours. - The link works while the invitation is pending (`Sent`) or accepted. It stops working once the invitation is declined, expires, or is cancelled. - The file is checked again on every click. If you stop sharing it with all partners, or turn off its download, links already in inboxes stop working. - Resending the invitation keeps its links. File links are available in the single-partner wizard only. The CSV and bulk invitation flows don't offer them. ```d2 direction: right insert: "You insert a file link\nin the Email step" { shape: rectangle } send: "The invitation email carries\na link named after the file" { shape: rectangle } click: "The recipient clicks the link\nno sign-in needed" { shape: rectangle } check: "Invitation still pending or accepted,\nand the file still shared with\nall partners and downloadable?" { shape: diamond } file: "The file downloads" { shape: rectangle } gone: "The link no longer\nopens the file" { shape: rectangle; style.stroke-dash: 3 } insert -> send -> click -> check check -> file: "yes" check -> gone: "no" ``` Continue with **Send From**, the recipient, and the rest of the steps above. ### Step 4: Review Confirm the partner, purpose, recipient, and email content are all correct, then click **Send Invitation**. Once sent, the partner appears in **All Partners** straight away, with the status `PENDING`. Until they answer, its row's **⋯** menu carries **Resend invitation** and **Cancel invitation**. See [Invitation Status and Expiry](#invitation-status-and-expiry). ## What Sending an Invitation Actually Does Sending an invitation doesn't just queue an email. Fours creates your side of the partnership straight away, with the status `PENDING`. That means an invited company is a real record from the moment you click send — you can open it, assign it a partner manager, attach notes, and register a co-sell against it without waiting for a reply. **All Partners** lists `ACTIVE` and `PENDING` partners together by default, so invited companies sit alongside accepted ones rather than hiding in a separate queue. `SUGGESTED` and `INACTIVE` partners stay out of that default view. ```d2 direction: right none: "No partnership" { shape: rectangle; style.stroke-dash: 3 } send: "You send an invitation" { shape: rectangle } pending: "Partnership PENDING\nopen it, assign a manager,\nattach notes, register a co-sell" { shape: rectangle } reply: "Recipient responds\nwithin 15 days?" { shape: diamond } active: "Partnership ACTIVE\nfiles, courses and journeys\ncan now be shared" { shape: rectangle } declined: "Invitation Declined\npartnership stays PENDING" { shape: rectangle } expired: "Invitation Expired\nthe link no longer works" { shape: rectangle; style.stroke-dash: 3 } cancelled: "Invitation Cancelled\nyou withdrew it" { shape: rectangle; style.stroke-dash: 3 } cosell: "You register a co-sell on their\nbehalf and they confirm it" { shape: rectangle } none -> send send -> pending: "your side is created immediately" pending -> reply reply -> active: "accepted" reply -> declined: "declined" reply -> expired: "no — a daily sweep expires it" pending -> cancelled: "you cancel it" cosell -> active: "the confirmation is the acceptance" expired -> send: "resend it, or send a new one —\nthe partner record is reused" cancelled -> send: "send a new invitation" ``` A few consequences worth knowing: - **You can't set `PENDING` by hand.** It's set by sending an invitation and nothing else. Editing a partner's status to `PENDING` is refused. - **One open invitation per company.** While an invitation to a company is waiting for an answer, you can't send another to anyone there. See [One Open Invitation per Company](#one-open-invitation-per-company). - **A later invitation reuses the existing record.** Once the first invitation has been answered, cancelled, or has expired, a new one to the same company reuses its partner record rather than creating a duplicate. An already-`ACTIVE` partner is never demoted back to `PENDING` for it either. - **A `PENDING` partner can't be shared with.** Files and courses only go to `ACTIVE` partners, so an invited company can't be a share target until they accept. - **Accepting isn't the only route to `ACTIVE`.** If you register a co-sell on a partner's behalf and they confirm it, that confirmation *is* the acceptance — the partnership flips `PENDING` → `ACTIVE`. ## One Open Invitation per Company Your organization can have only one open request with a company at a time, whichever side started it. Fours matches companies by email domain, so a colleague at the same company counts too. This keeps two requests for one company from crossing — for example, your invitation going out while that company's application sits in your queue — where accepting one would leave the other pending with nothing able to clear it. A company has an open request with you while it has any of these: - an invitation you sent that is still `Sent`, waiting for an answer; - an application from your [sign-up form](/prm/partner-registration-form/) that is still **Pending**; - a deal registration from your [public deal registration link](/prm/public-deal-registration-link/) held for your review. Accepted, declined, cancelled, and expired invitations and applications don't count, so an old request never stops a new one. An invitation another Fours organization sends you in the app isn't checked either. ```d2 direction: right start: "You invite a company,\nor it applies to you" { shape: rectangle } open: "Open request with\nthat company already?" { shape: diamond } theirs: "Their application or deal registration\nis waiting on you" { shape: rectangle } yours: "Your invitation is\nwaiting on them" { shape: rectangle } review: "Review their application,\nor decide the deal" { shape: rectangle } resend: "Resend your invitation,\nor wait for a reply" { shape: rectangle } go: "The new request goes through" { shape: rectangle } start -> open open -> theirs: "yes, theirs" open -> yours: "yes, yours" open -> go: "no" theirs -> review yours -> resend ``` ### What the invite wizard shows When you choose **Invite a new partner**, the notice under **Contact Email Address** says which kind of request is open, and shows the company's email domain so you can check it's the company you meant: | Notice | What it means | What to do | | --- | --- | --- | | **Already applied** · **Pending application** | The company applied, or registered a deal through your public link, on the date shown, and is waiting on you. | Click **Review their application**. The wizard closes and **Partners → Applications** opens on **Pending**, with that application highlighted. | | **Invitation already sent** · **Pending invitation** | Your invitation to the address shown, sent on the date shown, hasn't been accepted yet. | Click **Resend that invitation**, or wait for a reply. | **Next** stays disabled while the notice is showing. If you choose **Select recommended partner** instead, the wizard doesn't check ahead of time, and the send is refused when you click **Send Invitation**. ### In a bulk invitation A row whose company already has an open request isn't sent. It's listed as **Invitation pending** on the confirmation screen, and the rest of the batch still goes out. See [Step 7: Confirmation](#step-7-confirmation). ### When the company applies instead The rule works from the other side too. Someone at a company with an open invitation from you can't apply through your sign-up form: the form tells them to accept the invitation you sent. See [One Open Application per Company](/prm/partner-registration-form/#one-open-application-per-company). ## Invitation Status and Expiry Every invitation carries its own status, separate from the partnership status above: | Status | Meaning | | --- | --- | | `Sent` | Delivered and awaiting a response. The only state that can still be accepted, declined, or cancelled. | | `Accepted` | The recipient accepted. | | `Declined` | The recipient declined. | | `Expired` | Nobody responded before the deadline. | | `Cancelled` | You withdrew it. | Invitations expire **15 days** after they're sent. A daily sweep moves anything still `Sent` past its deadline to `Expired`. Past that point the link no longer works — the recipient can neither accept nor decline until you resend the invitation. ### Cancel a pending invitation Cancelling is the only change you can make to an invitation after sending it. 1. On **All Partners**, find the invited company's row. 2. Click the row's **⋯** menu and choose **Cancel invitation**. 3. Confirm on **Cancel this invitation?** — the dialog warns that the invitation link stops working and the contact can no longer accept it. Click **Cancel invitation** to go ahead, or **Keep it** to back out. The partner's row stays in **All Partners**, so you can invite the company again later. ### Resend a pending invitation While an invitation is waiting for an answer, the invited company's row on **All Partners** carries **Resend invitation** in its **⋯** menu, so a partner who lost the email does not need a fresh invitation record — the same one is sent again, and its 15-day window starts over. The actions follow the invitation rather than the partner's status: a partner who is already `ACTIVE` and whom you've invited again keeps them until that invitation is answered. If the email can't be sent, the accept-by date is still extended, and the message that confirms the resend says the email didn't go out. An **expired** invitation can be resent too. Its row no longer offers **Resend invitation**, so open the partner's record instead: while the partnership is still `PENDING`, the banner there offers **Resend invitation**. Resending brings the invitation back to `Sent` with a fresh 15-day window. A resend is refused while the company has another open request with you — for example, if a colleague there has applied in the meantime, or you've since invited someone else at the company. See [One Open Invitation per Company](#one-open-invitation-per-company). Right after a resend, wait a few minutes before resending the same invitation again. A cancelled invitation can't be resent. Send a new one instead; the partner record you already created is reused rather than duplicated, so nothing is lost by starting again. **If the invitation email didn't go out**, the invited company's row shows **Email not sent** under its contact email, so a failed send is never mistaken for an email nobody has opened yet. Hover over the marker to see why: | Why the email didn't go out | What to do | | --- | --- | | No connected mailbox could send it, and Fours' own fallback sender failed too. | Check your mailbox under **Settings → Integrations**, then resend. | | Your mailbox rejected it after Fours handed it over. | Check the mailbox's sent folder before you resend. | | The partner already uses Fours, but their pending invitation couldn't be found, so no email was sent. | Resend to retry. | | Anything else. | Resend to retry. | ## Invite multiple partners at once The bulk invitation modal opens in one of two modes, depending on how you reach it: | Mode | How you get there | Steps | | --- | --- | --- | | **CSV** | **+ Invite Partners → Import multiple from CSV** | Choose, Upload, Preview, Compose, Review, Confirmation | | **Pre-selected recipients** | Select rows in **Partner Discovery** — on the **Recommended Partners**, **From Your Marketplace**, or **From Your CRM** tab — and click **Invite Selected (N)** | Recipients, Compose, Review, Confirmation | Both end in the same place: one composed message, a recipients table to check, and a confirmation. The pre-selected mode skips the upload and preview steps because Fours already knows exactly who you picked. :::tip Selecting exactly one partner in Partner Discovery and clicking **Invite Selected (1)** opens the single-partner wizard instead of the bulk modal — one recipient doesn't need a batch. ::: The CSV walkthrough below covers the longer of the two paths. ### Step 1: Start the invitation 1. Go to **Fours Console**, then click **Partners**. 2. Click **+ Invite Partners**, then choose **Import multiple from CSV**. ![Invite Partners menu with the Import multiple from CSV option](images/invite-partners-to-your-network-6.png) ### Step 2: Download and prepare your CSV 1. Click **Download CSV template** to save a blank file with the correct column headers. ![Download CSV template button](images/invite-partners-to-your-network-7.png) 2. Open the file in a spreadsheet program, like Excel, Google Sheets, or Numbers. 3. Fill in one row per partner. Don't change, rename, or reorder the column headers in row 1 — Fours reads the file based on those exact headers. 4. Leave a cell blank if that column doesn't apply to a partner (**Contact Name**, **Partner Type**, and **Message** are optional). 5. Once every row is filled in, save the file. #### Partner Type values The **Partner Type** column takes the same set of engagement types the rest of PRM uses: | Code | Label | | --- | --- | | `RESELLER` | Reseller | | `VAR` | Value Added Reseller | | `REFERRAL_PARTNER` | Referral Partner | | `SYSTEMS_INTEGRATOR` | Systems Integrator | | `MSP` | MSP (Managed Service Provider) | | `TECHNOLOGY_PARTNER` | Technology Partner | | `AGENCY` | Agency | | `DISTRIBUTOR` | Distributor | | `AFFILIATE` | Affiliate | You can write either the code or the label — Fours matches case-insensitively and normalizes to the code. An unrecognized value passes through unchanged rather than failing the row, since the field is advisory. :::info **Reseller** and **Value Added Reseller** are two distinct types, not synonyms, and Fours keeps them apart: a reseller moves the licence transactionally, while a value-added reseller bundles its own integration or services with it. Writing "Reseller" never resolves to `VAR`. ::: A single send takes at most **200** partners, so split a longer list across several files. ### Step 3: Upload your CSV 1. Click **Choose CSV File**, or drag and drop your file onto the upload area. 2. Click **Next**. ### Step 4: Preview and validate Fours checks your file and shows a summary of **Total rows**, **Valid** rows, **Errors**, and **Duplicates**, along with a row-by-row breakdown. 1. Fix any rows marked with errors before continuing. Click the **trash** icon next to a row to remove it from the batch. 2. Correct a row's **Partner Type** in place if the CSV got it wrong. The column is a dropdown here, offering the same nine types listed above plus a blank choice for no type. 3. Click **Next** once you're ready to proceed. ![CSV preview with validation summary and row-by-row breakdown](images/invite-partners-to-your-network-8.png) ### Step 5: Compose your message 1. Confirm the account under **Send from**. 2. Select an **Email tone** from the dropdown: Executive, Sales, Technical, Alliance-Focused, or Short & Tactical. 3. Select a **Purpose**: Network Invitation, Account Overlap, or Deal Collaboration. 4. Click **Generate with AI** to draft a subject and message body, or write your own. :::info The message body you write here only applies to partners who don't already have their own **Message** filled in from your CSV. Any row with its own message keeps that message instead. ::: 5. Click **Next**. ### Step 6: Review and send 1. Review the **Purpose**, **Tone**, **Subject**, and message template. 2. Check the **Recipients** table to confirm every partner and email address is correct. The **Custom?** column shows **Yes** for any partner using their own CSV message instead of the shared template. 3. Click **Invite [number] partners** to send. ![Review screen with recipients table before sending](images/invite-partners-to-your-network-9.png) ### Step 7: Confirmation Fours shows how many invitations were sent, along with counts for **Skipped** and **Errors**. Each partner that wasn't sent is listed underneath with its email, a status, and the reason: - **Invitation pending** — the company already has an open invitation or application with you, including one that an earlier row of the same file has just sent. See [One Open Invitation per Company](#one-open-invitation-per-company). - **Skipped** — the company is already one of your linked partners. - **Failed** — anything else. The reason says what went wrong. In a CSV file, a row whose email is on a personal email provider (the [list above](#step-2-purpose)) fails this way, and its **Detail** reads, for a `gmail.com` address, *"Partner invitations must go to a work email address; gmail.com is a personal email provider."* The rest of the batch still goes out. Click **Done** to close the wizard. Once sent, every invited partner appears in **All Partners** straight away, with the status `PENDING`, and its row carries **Resend invitation** and **Cancel invitation** until they answer. ![Confirmation screen with sent, skipped, and error counts](images/invite-partners-to-your-network-10.png) ## Next step Once you've sent your invitations, see [Track Partner Collaborations](/prm/collaborations/) to follow their status and know when to follow up on ones that have gone quiet. --- Source: https://doc.fours.com/prm/collaborations/ # Track Partner Collaborations Every invitation you send or receive creates a collaboration thread. Follow the ones you've sent from each invited partner's row on the **All Partners** tab, and review every application you've received under **Applications**. --- ## Overview There is no separate Collaborations page. Invitations and applications show up in these places under **Partners**: - **Invitations you send** are rows in the **All Partners** table. Sending an invitation creates the partner record straight away, with the status `PENDING`, so the company is listed from the moment you click send. While the invitation is waiting for an answer, the row's **⋯** menu carries **Resend invitation** and **Cancel invitation**. See [Invite Partners](/prm/invite-partners/#invitation-status-and-expiry). - **Applications** is a list of its own in the Partners rail. It keeps every inbound request — submissions from your sign-up form and invitations other Fours organizations send you in the app — including the ones you've already decided, so you can see which applications you accepted, declined, or let expire. See [Review Partner Applications](#review-partner-applications). If you're an Admin, it also has a **User access** sub-tab for the people asking to join your own organization. See [Review requests to join your organization](#review-requests-to-join-your-organization). - **The Pending invitations panel** is for organizations that joined Fours as a partner. They have no **Applications** list, so an invitation a seller sends them waits in a **Pending invitations** panel above their All Partners table until they answer it. ## Open an invitation's details **An invitation you sent.** On the **All Partners** tab, the invited company's row shows who you wrote to: when the partner record has no contact of its own yet, **Contact Name** and **Contact Email** show the person you invited. If the invitation email couldn't be sent, **Email not sent** appears under the contact email; hover over it for the reason. Click the partner's name to open the record: its banner says when the invitation was sent, the date it must be accepted by (or the date it expired), and the address it went to. **An invitation sent to you**, if your organization joined Fours as a partner: 1. Go to **Fours Console**, then **Partners**. 2. On the **All Partners** tab, expand **Pending invitations**. The panel appears only while something is pending, and it opens by itself if you don't have any partners yet. 3. Click a row to expand it in place and see what the company sent you — the same details **Applications** shows. See [Read an application](#read-an-application). Click the row again to close it. The panel lists up to 50 invitations, newest first. When more are pending, a **Showing 50 of N** line at the bottom says so. Each row's actions sit behind the **⋯** menu in the **Actions** column. ## Respond to an inbound invitation **If your organization joined Fours as a partner**, open the row's **⋯** menu in **Pending invitations** and choose **Accept** or **Decline**. They do exactly what **Approve** and **Decline** do on the **Applications** list (see [Review Partner Applications](#review-partner-applications)), except that a decline here takes effect straight away, without a confirmation step. **If your organization runs its own partner program**, an invitation from another Fours organization arrives under **Applications**. Approve or decline it there. ## Cancel an invitation you sent 1. On the **All Partners** tab, find the invited company's row and open its **⋯** menu. 2. Choose **Cancel invitation**. 3. Confirm on **Cancel this invitation?** — the dialog warns that the invitation link stops working and the contact can no longer accept it, and that the partner row stays, so you can invite the company again later. Click **Cancel invitation** to go ahead, or **Keep it** to back out. :::warning Cancelling cannot be undone. To work with that partner afterwards you have to send a fresh invitation — see [Invite Partners](/prm/invite-partners/). ::: ## Review Partner Applications **Applications** is the full history of requests to partner with you. It includes every submission from your public [registration form](/prm/partner-registration-form/) and every invitation another Fours organization sends you in the app. It also holds an application for each company that registers a deal through your [public deal registration link](/prm/public-deal-registration-link/) without being your partner yet. Rows you've decided stay in the list, including the ones you turned down. 1. Go to **Fours Console**, then **Partners**. 2. Click **Applications** in the rail. If you're an Admin, it opens on the **Partnership** sub-tab, which is this list; a count beside **Partnership** shows how many applications are pending. 3. Pick a status to narrow the list: **All**, **Pending**, **Accepted**, **Declined**, or **Expired**. The table shows each **Applicant**, their **Domain**, the **Status**, when the application was **Submitted**, and when it was **Decided**. The newest are listed first, 20 to a page. The list doesn't show which teammate made a decision. | Status | Meaning | | --- | --- | | **Pending** | Waiting for your decision. The only status with **Approve** and **Decline**. | | **Accepted** | You approved it. | | **Declined** | You declined it. It can't be reopened. | | **Expired** | Nobody decided within 15 days. | A row stays **Pending** until you approve or decline it. If nobody decides within 15 days of its arrival, it can no longer be approved or declined, and a daily check marks it **Expired**. If the other organization resends an in-app invitation, it comes back as **Pending** with a new 15-day window. ```d2 direction: right arrives: "An application arrives\nregistration form or\nin-app invitation" { shape: rectangle } pending: "Pending" { shape: rectangle } accepted: "Accepted" { shape: rectangle } declined: "Declined\ncan't be reopened" { shape: rectangle } expired: "Expired" { shape: rectangle; style.stroke-dash: 3 } arrives -> pending pending -> accepted: "you approve" pending -> declined: "you decline and confirm" pending -> expired: "no decision within 15 days" expired -> pending: "the other organization\nresends an in-app invitation" ``` ### Read an application Click the arrow at the start of a row to read what the company sent before you decide. Only one row is open at a time. For an application from your sign-up form, the panel shows: - **Submitted by** — the applicant's name and email address; - **Company** and **Company website**, which opens in a new tab; - their answer to **Why do you want to partner with us?**; - every other question with its answer, worded as the applicant saw it and in the order the form asks them now. A question you've renamed or removed since then comes after the rest. A question the applicant skipped reads *Not answered*, and a ticked checkbox reads *Yes*; - the form it came through — or *the deal registration form*, for a company that registered a deal through your public link. An invitation from another Fours organization has no form behind it. Its panel says so, and shows the message the organization sent instead. When you arrive from the invite wizard's **Review their application** link, the list opens on **Pending** with that application highlighted. See [Invite Partners](/prm/invite-partners/#one-open-invitation-per-company). ### Approve an application Click **Approve** on a **Pending** row. Approving marks the row **Accepted** and provisions the partner. When provisioning succeeds, Fours reuses and activates a matching partner record if it finds one, and otherwise creates a new active partner record. For an invitation from another Fours organization, both organizations get an active partner record. For an application from your sign-up form or your public deal registration link, Fours identifies the company by the domain of the applicant's work email, never by the **Company Website** they typed. It reuses, in this order: 1. the partner record the application was raised against, for a company that registered a deal through your public link; 2. a partner whose linked Fours organization is on that email domain; 3. a partner record with that domain. If none of these exists, Fours creates a new partner record for the domain. As long as the applicant's work email is on that partner record's domain, approving also sets up the partner's side: - **Their Fours organization.** Fours links the company's existing Fours organization, or creates one. - **The applicant's access.** Fours adds the applicant to that organization, as an **Admin** if nobody is in it yet and as an **Editor** otherwise. Nobody's existing role changes. - **Your company in their portal.** The partner's portal lists your company as a partner. - **Their copy of a registered deal.** For an application raised by a [public deal registration](/prm/public-deal-registration-link/), each deal registered with that application that is still waiting for your decision gets a copy in the partner's organization, in `Pending Acceptance`. Approving the partner doesn't accept the deal: you still accept or reject it in **Partner Co-Sells**. Provisioning is best-effort. If it can't complete, the application still reads **Accepted**, but the partner's side may be missing. For example, an application from a personal email address, such as Gmail, gets no partner record (the sign-up form now refuses these, so only older ones remain), and an applicant whose email isn't on the company's domain isn't given access. To bring such a partner in, invite them at a work email address. See [Invite Partners](/prm/invite-partners/). ### Decline an application 1. Click **Decline** on a **Pending** row. 2. Confirm with **Decline application**. A decline can't be undone, and there is no way to reopen the application from the console. A partner who should have been accepted has to apply again. The one exception is an application raised by a [public deal registration](/prm/public-deal-registration-link/). If you later accept that company's deal in **Partner Co-Sells**, the company becomes your partner and its application reads **Accepted**, even if you had declined it or it had expired. For a public-form application, the **Partnership invite declined** email in your **Settings → Notification** controls whether the applicant is emailed. See [Email Notification](/settings/email-notification/). ## Review requests to join your organization **User access** is the second sub-tab of **Applications**, and only Admins see it. It lists the people asking to join your own organization in Fours — the same join requests Admins review under [Settings > Users & Roles](/get-started/account/#review-join-requests) — and keeps the ones you've already decided. Anyone who isn't an Admin sees the partner applications only, with no sub-tabs. 1. Go to **Fours Console**, then **Partners**. 2. Click **Applications** in the rail, then **User access**. A count beside it shows how many requests are waiting. 3. Pick a status: **Pending**, where the list opens, **Approved**, **Rejected**, or **All**. To narrow it further, use the role filter (**Any role**, **Viewer**, **Editor**, or **Admin**) or **Search name or email**. Click **Name**, **Role**, **Status**, or **Request date** to sort by that column, and click it again to reverse the order. On any status but **Pending**, a **Decided** column shows who decided each request and when. Click a row to read the whole request: who asked, your organization, the role they asked for, when they asked, and their full message. A decided row also shows the outcome, who decided it and when, and either the role granted or the reason given. Each pending row has its own **Approve** and **Reject**, which work the way they do under [Review Join Requests](/get-started/account/#review-join-requests). ### Decide several requests at once 1. Tick the pending rows you want, or tick the box in the header to select every pending row on screen. 2. Click **Approve selected** or **Reject selected**. The confirmation lists everyone you selected. - To approve, choose **Keep each requested role**, or one role for everyone, such as **Editor for everyone**. - To reject, you can give one reason, which is sent to everyone selected. 3. Confirm. Fours decides each request separately, so one that fails doesn't stop the rest, and the message afterwards says how many failed. **Clear** drops your selection. A request marked **Already a member** is left out of a bulk rejection, because only **Approve** can clear it. ## Start a new invitation Invitations are created from the invite wizard rather than from the partner list. See [Invite Partners](/prm/invite-partners/) for the single and bulk flows. --- Source: https://doc.fours.com/prm/partner-discovery/ # Partner Discovery Discover and invite partners without leaving Fours, using AI-assisted recommendations, the resellers already moving your product on a marketplace, or partner companies you track in Salesforce. --- ## Overview Partner Discovery helps you find new partners and invite them into your network. You can source partners three ways: - **Recommended Partners** — AI-assisted recommendations generated from your existing partner and co-sell data. - **From Your Marketplace** — resellers your organization has already transacted with on a cloud marketplace. - **From Your CRM** — partner companies that already exist in Salesforce and have been configured as partners. Use Partner Discovery to identify new partnership opportunities, formalize the resale relationships you already have, or quickly invite partners you already track in Salesforce. ```d2 direction: right sync: "Fours analyzes what\nyour org already has" { shape: rectangle } crm: "Salesforce accounts\nmatching your partner rule" { shape: rectangle } data: "Partner, referral, CRM and\nco-sell data" { shape: rectangle } txn: "Marketplace transactions\nwith a reseller" { shape: rectangle } candidate: "Candidate saved as\na SUGGESTED partnership" { shape: rectangle } transacted: "Has marketplace transactions\nwith your org?" { shape: diamond } rec: "Recommended Partners tab\nconfidence meter · potential revenue" { shape: rectangle } mkt: "From Your Marketplace tab\ndeal count · revenue transacted" { shape: rectangle } crmtab: "From Your CRM tab" { shape: rectangle } invite: "Invite → partnership\nbecomes PENDING" { shape: rectangle } data -> sync txn -> sync sync -> candidate candidate -> transacted transacted -> mkt: "yes" transacted -> rec: "no" crm -> crmtab rec -> invite mkt -> invite crmtab -> invite ``` ## Navigate to Partner Discovery 1. Go to **Fours Console**, then click **Partners**. 2. Click **Partner Discovery**. 3. Switch between the **Recommended Partners**, **From Your Marketplace**, and **From Your CRM** tabs to see each source. :::info Recommended Partners and From Your Marketplace are two views of the same underlying population — companies Fours surfaced that you have never acted on. What separates them is evidence: a candidate that has actually transacted with you on a marketplace shows on the Marketplace tab, and everyone else shows on Recommended. This sorts itself out over time. When a recommended company later starts transacting with you, the sync attaches that activity to the same record and the candidate moves to the Marketplace tab on its own — which is right, because you now have proof of a real relationship. ::: ## Recommended Partners The **Recommended Partners** tab shows AI-assisted recommendations generated from the partner, referral, CRM, and co-sell data already available in your Fours account. These recommendations aren't pulled from a generic company directory. Instead, Fours analyzes the relationship and opportunity data already available in your organization to surface potential partners that may be relevant for collaboration opportunities. Use this tab when you're: - Expanding your partner network using existing relationship data - Looking for partners that may help create or accelerate opportunities - Prioritizing which partners to engage first ![Recommended Partners tab showing AI-assisted partner recommendation cards](images/find-and-invite-partners-with-partner-di-1.png) :::info If no recommendations appear, your account may not yet have enough partner or co-sell data to generate suggestions. ::: ### Understanding the Recommendation Cards Each recommendation card includes: - **Partner Type** — The type of partner, such as a reseller. - **Confidence** — A three-bar meter next to a `High`, `Medium`, or `Low` label, so you can rank outreach at a glance. - **Company size** — A `Small`, `Medium`, or `Large` badge. Hover it to see the employee count behind the label. - **Recommended Targets** — Customer accounts where Fours has identified potential overlap or co-sell opportunities with this partner. Reads `No matches` when there is no overlap to show. - **Potential Revenue** — An estimated revenue opportunity associated with the partnership, based on the data available in your account. The confidence label is derived from the recommendation's score: | Label | Score | | --- | --- | | High | 0.7 and above | | Medium | 0.4 up to 0.7 | | Low | Below 0.4 | Company size follows the headcount Fours has on the company: | Badge | Employees | | --- | --- | | Small | Fewer than 100 | | Medium | 100 to 999 | | Large | 1,000 or more | ![A Recommended Partners card — the partner name with its confidence meter reading High, a short profile, the relationship badge, the recommended target account, the potential revenue, and the Invite button](images/42-recommended-partner-card.png) :::info Recommendations are designed to help you prioritize potential partnerships. They are not guarantees of revenue or partnership success. Channel badges — the marketplace logos showing where a company sells — appear on **From Your Marketplace** cards, where the transactions that prove the channel exist. A Recommended card has no transactions behind it yet, so it shows no channel badges, and the channel quick filter empties that tab. ::: ### Who Doesn't Appear Here Discovery only suggests companies you haven't acted on. A company drops out of the recommendations once your relationship with it has a real state: - **Active** partners — already in your network. - **Inactive** partners — you've already decided about them. - **Pending** partners — you've invited them and are waiting on a reply. An invitation counts as having found them, so Fours stops re-suggesting a company you already reached out to. That leaves `SUGGESTED` — companies Fours surfaced that you have never acted on — as the population the Recommended Partners tab draws from. ### Partners That Promote Themselves A **Pending** company — one you invited and are waiting on — that starts producing real marketplace revenue with you is promoted to **Active** automatically. You already initiated the relationship, and money moving is stronger evidence that it is live than a status field is, so Fours stops treating the company as a lead and moves it into **All Partners**. The trigger is *realized* revenue — revenue already disbursed. Upcoming or projected revenue does not promote anyone, since it hasn't happened yet. :::info `SUGGESTED` companies are deliberately **not** promoted this way, however much they transact. Nobody invited them and nobody accepted, so promoting them on the strength of the same marketplace activity that surfaced them would make the discovery signal its own confirmation — and fill **All Partners** with records that have no contacts, tier, journey, or partner manager. They stay `SUGGESTED` until you invite them and they accept. Promotion is also one-way and never overrides a decision you made. A partner you deliberately set to **Inactive** stays inactive no matter how much revenue arrives. ::: ### How to Use These Recommendations Partner Discovery helps you decide where to focus your outreach efforts. A simple approach is: 1. **Start with High confidence recommendations.** These recommendations generally have stronger signals in your organization's data. 2. **Review the Recommended Targets.** Look for customer accounts where the partner may be able to help create or accelerate opportunities. 3. **Evaluate the opportunity.** Consider whether the account overlap and estimated revenue opportunity make the partnership worth pursuing. 4. **Personalize your outreach.** When sending an invitation, reference the shared account or opportunity in the **Context for this engagement** field so the invitation feels relevant rather than generic. ![Recommendation card detail with Recommended Targets and Potential Revenue](images/find-and-invite-partners-with-partner-di-2.png) ## From Your Marketplace The **From Your Marketplace** tab shows resellers your organization has already transacted with on a cloud marketplace. These are the strongest candidates in the product: the relationship exists commercially, it just isn't a formal partnership in Fours yet. Fours builds this list by grouping your marketplace transactions by reselling company, so nothing has to be configured for the tab to fill in. **A reseller has to have been paid to appear here.** The tab lists companies with at least **$10,000** in disbursed CPPO revenue. Upcoming and unrealized revenue does not count, and neither does deal count — CPPO paperwork is not money. The floor exists so the tab holds real commercial relationships rather than every company that once appeared on a resale document. :::note The threshold is compared against the revenue total as reported, which is not always converted to USD. It is deliberately approximate rather than falsely precise; treat a company sitting near the line as a judgement call. ::: ### What a Marketplace Card Shows A marketplace card swaps the recommendation-specific fields for the transaction record behind the company: | Field | What it holds | | --- | --- | | **Deal count** | The number of deals transacted with this reseller, shown in place of the confidence meter. | | **Reseller Account** | The reseller's account identifier on each channel, as `channel · id`. Reads `Not reported` when the channel didn't supply one. | | **Last transaction** | The date of the most recent transaction. | | **Revenue Transacted** | Actual revenue through this reseller, shown in place of Potential Revenue. | Channel badges appear here too — the marketplaces this company has actually transacted on. :::info There is no confidence meter on a marketplace card. Confidence scores are only calculated for recommendations, so a meter here would read `Low` on every card — the weakest possible verdict on the strongest candidates you have. The deal count occupies that slot instead. ::: The list view of this tab carries the same four columns: **Reseller Account**, **Revenue Transacted**, **Deals**, and **Last Transaction**. Use the **Columns** button to choose which ones you want. ### These Resellers Are Candidates, Not Partners A reseller Fours finds this way is created as `SUGGESTED`. It is a candidate you can see and invite, not a partnership — nobody sent an invitation and nobody accepted one, so calling it active would assert a relationship that does not exist. In **All Partners** they carry an amber `SUGGESTED` status badge, distinct from the blue `PENDING` of a partner you invited and the green `ACTIVE` of one who accepted — so a discovered reseller is never mistaken for a recruited partner. Filter the **Status** column to `SUGGESTED` to see just this population. They become real partners the same way everyone else does: you invite them, and they accept. ## From Your CRM The **From Your CRM** tab shows partner companies that already exist in Salesforce. During Salesforce setup, you tell Fours how to identify which Salesforce accounts should be treated as partners — for example, accounts where `Type = Partner`. Any accounts that match that rule automatically appear in this tab. **Companies you have already connected are hidden by default.** The tab is for finding partners you do not have yet, so an account that is already a partner in Fours would be noise. A **Show already connected (n)** toggle brings them back when you want to check one. Use this tab when you already manage partner companies in Salesforce and want to invite them to Fours without manually entering their information. :::info Before you can use this tab, you must first connect Salesforce and set up which Salesforce accounts should be treated as partners. See [Sync Partners from Salesforce](/prm/sync-partners-from-salesforce/). ::: ![From Your CRM tab listing partner accounts synced from Salesforce](images/find-and-invite-partners-with-partner-di-3.png) Once your CRM configuration is saved: - Matching partner accounts automatically appear here. - Company names and contact emails are pre-filled from Salesforce. - You can invite one or more partners directly from the results. ## Invite Partners You Discover After identifying partners on any of the three tabs, you can invite them directly. - Click **Invite** on an individual partner card to invite one company. ![Invite button on an individual partner card](images/find-and-invite-partners-with-partner-di-4.png) - Select multiple partners and click **Invite Selected** to send invitations in bulk. ![Selecting multiple partners and choosing Invite Selected for a bulk invitation](images/find-and-invite-partners-with-partner-di-5.png) Partner Discovery uses the same invitation workflow as manual invitations. For detailed instructions on inviting partners, see [Invite Partners](/prm/invite-partners/). --- Source: https://doc.fours.com/prm/build-a-training-course/ # Build a Partner Training Course Use the course builder to create partner training on positioning, pricing, or product knowledge — either by building lessons directly in Fours or by uploading an existing SCORM package. --- ## Overview You can build a training course three ways: create lessons directly in Fours with the editor, upload a course you already built in another authoring tool as a SCORM package, or **link a course that lives in your own LMS** — see [Connect an External LMS](/prm/connect-an-external-lms/). Once the course is published, you can optionally award a certificate on completion and track learner progress from the **Training** dashboard. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ### The Certification Chain Building a course is the first link in a chain that ends with a certificate in your partner's hands. Five guides cover it, and it helps to see where each one sits before you start — particularly the two written for the partner rather than for you. ```d2 direction: right seller: "You — the seller, in the Fours Console" { cert: "Create a certificate\ncolors · issuer · validity · renewal" { shape: rectangle } build: "Build the course\neditor or SCORM package" { shape: rectangle } attach: "Attach the certificate\nCertificate(s) granted on completion" { shape: rectangle } publish: "Publish the course" { shape: rectangle } share: "Share it with partner orgs\nall partners, or specific ACTIVE ones" { shape: rectangle } monitor: "Monitor\nPartner Progress · Enrollments · Certified" { shape: rectangle } } partner: "Your partner — in their portal" { find: "Finds it under\nTraining → From Partners" { shape: rectangle } take: "Takes it, or assigns it\nto teammates" { shape: rectangle } earn: "Completes every lesson\nand earns the certificate" { shape: rectangle } view: "Reviews and prints it under\nTraining → Certificates" { shape: rectangle } } seller.cert -> seller.attach: "must exist first" seller.build -> seller.attach seller.attach -> seller.publish seller.publish -> seller.share: "publishing is not sharing" seller.share -> partner.find partner.find -> partner.take partner.take -> partner.earn partner.earn -> partner.view partner.earn -> seller.monitor: "shows on your Certified list" { style.stroke-dash: 4 } partner.take -> seller.monitor: "progress reported back" { style.stroke-dash: 4 } ``` | Stage | Guide | | --- | --- | | Build and publish the course | This page | | Create the certificate it awards | [Partner Certifications](/prm/partner-certifications/) | | Share it and watch progress | [Share and Monitor Partner Training Courses](/prm/share-monitor-training/) | | What the partner does with it | [Take a Partner Training Course](/prm/take-training-course/) | | How the partner reads their certificates | [View Your Team's Earned Certificates](/prm/view-certificates/) | :::tip Create the certificate **before** the course if you know the course will award one. **Certificate(s) granted on completion** can only point at a certificate that already exists, so building it first saves a trip back through the course editor. ::: ## Where Training Lives Everything in this guide happens under **Partners → Training**, which is organized into four tabs: | Tab | What it holds | | --- | --- | | **My Courses** | Courses your organization authors — where you build, publish, and share. | | **Partner Progress** | How partner learners are doing across your courses. | | **From Partners** | Courses partners have shared *with* you, for your own team to take. | | **Certificates** | Certificates you offer, and the ones learners have earned. | If your organization joined Fours as a partner rather than running its own program, you only see **From Partners** and **Certificates** — there is no authoring side to show. ## Step 1: Choose How to Create a Course 1. Go to **Fours Console**, then **Partners**. 2. Click **Training**, then **+ Create Course**. 3. Choose one of three paths: - **Build with editor** — create lessons directly in Fours. - **Upload SCORM package** — import an existing SCORM 1.2 or SCORM 2004 course created in another authoring tool. - **Link external LMS** — publish a course that stays in your own learning management system. It asks only for a course name, destination link, LMS, category and estimated minutes; Fours does not host the lessons. Once completion sync is set up, it also offers **Course in your LMS**, so completions can come back to Fours. To sign partners in on arrival, [connect your LMS](/prm/connect-an-external-lms/); without that connection, the course opens at its destination link. ![Create Course dialog offering Build with editor or Upload SCORM package](images/build-a-partner-training-course-1.png) ## Step 2: Create the Course Follow **Option 1** to build content in Fours, or **Option 2** to upload a SCORM file. ### Option 1: Build a Course with the Editor Use this method if you want to create and manage course content directly in Fours using modules, lessons, and quizzes. #### Start the course 1. Enter the **Course name**, then click **Create**. 2. Under **Certificate(s) granted on completion**, select a certificate to award when learners complete the course. Leave this field blank if the course doesn't grant a certificate. :::info To create a certificate, see [Partner Certifications](/prm/partner-certifications/). ::: ![Course settings with the Certificate granted on completion field](images/build-a-partner-training-course-2.png) 3. Click **Add module** to create a section, then rename it. ![Add module button in the course editor](images/build-a-partner-training-course-3.png) 4. Inside the module, click **Add lesson** and rename it. ![Add lesson button inside a module](images/build-a-partner-training-course-4.png) 5. Click inside the lesson body and type **/** to insert content blocks. ![Slash menu for inserting content blocks in a lesson](images/build-a-partner-training-course-5.png) 6. Repeat for each module and lesson the course needs. #### (Optional) Add a graded quiz Insert a **Quiz** block inside a lesson to test what the partner just learned. 1. Enter the question text. 2. Click **Add option** to add an answer choice. 3. Click **Correct** next to the right answer. 4. Click **Add question** to add more questions. 5. Set the **Passing score %** and **Max attempts** at the bottom of the quiz block. ![Quiz block with question, answer options, passing score, and max attempts](images/build-a-partner-training-course-6.png) #### Preview the course Click **Preview** in the top-right toolbar to open Learner Preview mode. Use this to catch formatting issues, confirm quiz answer options display correctly, and confirm modules appear in the right order before you publish. ![Learner Preview mode showing the course as a partner will see it](images/build-a-partner-training-course-7.png) #### Save or publish the course - Click **Save draft** to keep your changes private while you're still building the course. - Click **Publish** to make the course available for partners to enroll in. ![Save draft and Publish options in the course editor](images/build-a-partner-training-course-8.png) ### Option 2: Upload a SCORM Package Use this method if your course is already built in an external authoring tool (like Articulate or iSpring) and exported as a SCORM file. If you're writing the course content directly in Fours, use **Build with editor** instead. :::warning You can't edit lesson content inside Fours after uploading. To make changes, update the course in your original authoring tool, export a new SCORM package, and replace the file in Fours. ::: #### What Fours accepts | Requirement | Detail | | --- | --- | | SCORM version | **SCORM 1.2** or **SCORM 2004**. | | File format | A single **`.zip`**. | | Manifest | **`imsmanifest.xml` must sit at the root of the zip**, not inside a folder. | | Maximum size | **50 MB**. | The manifest is what Fours reads to work out the course structure, so most upload failures come down to zipping the *folder* that contains the course instead of its *contents*. If your archive opens to a single folder, re-zip from inside it. The course title and description from the manifest pre-fill the new course. Both stay editable afterward. :::info A package over 50 MB is rejected before it is examined, so you'll see a size error rather than a content error. Trim embedded video and high-resolution assets in your authoring tool, or host the heavy media externally and link to it. ::: 1. Click **Choose .zip** to upload your SCORM file. Fours imports the course and creates it as a draft using the name and structure defined in the SCORM package. 2. Under **Certificate(s) granted on completion**, select a certificate to award when learners complete the course. Leave this field blank if the course doesn't grant a certificate. :::info To create a certificate, see [Partner Certifications](/prm/partner-certifications/). ::: 3. Check the **Preview** tab to confirm it matches what learners will see. ![Preview tab of an uploaded SCORM course](images/build-a-partner-training-course-9.png) 4. To update the content, click **Replace package** and upload the new zip. This replaces the entire course, so make sure the new file already includes all your changes. 5. Save or publish the course: - Click **Save draft** to keep your changes private while you're still building the course. - Click **Publish** to make the course available for partners to enroll in. ![Save draft and Publish options for a SCORM course](images/build-a-partner-training-course-10.png) ## Reference: Training Statuses **Course status** — where a course sits in its own lifecycle: | Status | Meaning | | --- | --- | | `Draft` | Still being built. Not visible to learners. Each course has at most one draft at a time. | | `Published` | Live and enrollable by whoever the course is shared with. | | `Archived` | Retired. Kept for the record rather than for new enrollments. | **Course kind** — how the content was made: | Kind | Meaning | | --- | --- | | `native` | Authored in Fours' editor as modules and lessons. | | `scorm` | An uploaded SCORM package, hosted as-is. | | `external` | A link to a course that runs in your own LMS. See [Connect an External LMS](/prm/connect-an-external-lms/). | **Enrollment status** — where one learner stands. Fours works this out from their lesson progress and quiz attempts — for an external course, from their opens and any completion your LMS reports — rather than storing it, so it's always current: | Status | Meaning | | --- | --- | | `Not Started` | Enrolled, no progress yet. | | `In Progress` | Partway through. | | `Opened` | External courses only: the learner has followed the link to your LMS. The furthest an external course goes without completion sync. | | `Completed` | Finished, and any required quiz passed. For an external course, your LMS reported the completion through [completion sync](/prm/connect-an-external-lms/#completion-sync). | | `Failed` | A required quiz ran out of attempts with no passing score. | **Certificate status** — the state of a certificate someone already earned. Also derived, from the expiry and supersede dates: | Status | Meaning | | --- | --- | | `Active` | Valid. | | `Expires Soon` | Within **30 days** of expiring. This is also the window in which a retake can renew it early. | | `Expired` | Past its expiry date. | | `Renewed` | A newer issue of the same certificate replaced this one. The old row stays visible as history. | ## Working With the Certificates Tab The **Certificates** tab lists what learners have earned. Filter it by **Certificate**, **Issuer**, and **Status**, search across learner, certificate, and course names, and use the **Columns** button to choose which columns you want — your choice is remembered for next time. Per-row actions live behind the **⋯** kebab menu in the **Actions** column, **Retake** among them. :::warning **Retake resets progress.** Retaking a course wipes your lesson progress and quiz history for it, and you have to pass again to renew the certificate. Fours asks you to confirm before it does this. ::: ## Next Steps Publishing a course doesn't automatically make it visible to partners. See [Share and Monitor Partner Training Courses](/prm/share-monitor-training/) to choose who can access your course and track learner progress and completion. --- Source: https://doc.fours.com/prm/partner-certifications/ # Partner Certifications Certifications help partners prove they've completed your training and let you track who's qualified to sell or support your product. --- ## Overview In this guide, you'll learn how to create and manage certificates, assign them to courses, and see which learners have earned them. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Create a Certificate 1. Go to **Fours Console**, then **Partners**. 2. Click **Training**, then open the **Certificates** tab. 3. Click **+ New certificate**. ![New certificate button on the Certificates tab](images/create-manage-and-assign-partner-certifi-1.png) 4. Give the certificate a **Name** and **Description**. 5. Set the **Background color**, **Text color**, and **Accent color**. Use the hex input or the color swatch. 6. Optionally add a **Background image URL** and **Logo URL**. :::info These fields take a hosted image link, not a file upload. Upload your logo to wherever your team hosts images first, then paste the resulting URL here. ::: 7. Enter **Issued by** — the name or team shown as the issuer on the certificate. 8. Set **Validity**. Options are **No expiry**, **6 months**, **1 year**, **2 years**, or **3 years**. 9. If you set a Validity other than "No expiry," a **Renewal** field appears. Choose: - **Manual retake** — the learner renews voluntarily. - **Auto re-enroll** — the learner is re-enrolled automatically. 10. Check the **Live Preview** on the right to confirm the certificate looks right. 11. Click **Create**. ![Certificate editor with details, colors, validity, and live preview](images/create-manage-and-assign-partner-certifi-2.png) ## Edit or Delete a Certificate 1. Go to **Fours Console**, then **Partners**. 2. Click **Training**, then open the **Certificates** tab. 3. Click the pencil or trash icon next to the certificate to update or delete it. ![Edit and delete icons on a certificate row](images/create-manage-and-assign-partner-certifi-3.png) ## Assign a Certificate to a Course Certificates aren't linked to a course automatically — assign them from inside the course builder. 1. Go to **Fours Console**, then **Partners**. 2. Click **Training**, then open the **My Courses** tab. 3. Under **Certificate(s) granted on completion**, search for and select the certificate. For the full course creation process, see [Build a Partner Training Course](/prm/build-a-training-course/). ## Check Who's Certified This only applies if the course has a certificate attached under **Certificate(s) granted on completion**. If that field is blank, the course doesn't award a certificate. If a certificate is attached: 1. Open the course from **Partners** → **Training** → **My Courses**. 2. Click **Certified** in the top toolbar. 3. Review the list of learners who've earned the certificate, grouped by partner organization. Each row shows the certificate name, **version** (the course version the learner completed), issue date, expiry date, and status (`Active`). ![Certified learners list grouped by partner organization](images/create-manage-and-assign-partner-certifi-4.png) :::warning If you republish a course after a learner is already certified, their certificate stays tied to the version they completed — it doesn't update automatically to the new version. ::: --- Source: https://doc.fours.com/prm/share-monitor-training/ # Share and Monitor Partner Training Courses Publishing a course doesn't automatically make it visible to partners. Before anyone can enroll, choose which partner organizations can access it, then track their progress as they complete the training. --- ## Overview Sharing and monitoring a course happens in two stages: - **Share the course** with the right partner organizations so learners can discover and enroll. - **Monitor progress** as learners work through the course and see who has earned a certificate. ## Share a Course with Partners 1. Open the course: 1. Go to **Fours Console**, then **Partners**. 2. Click **Training**, then **My Courses**. 3. Open the course you want to share. 2. Set sharing: 1. Click **Share** in the top toolbar. ![Share button in the course top toolbar](images/share-and-monitor-partner-training-cours-1.png) 2. Choose how you want to share it: - **Private**: Only your organization can see this course. - **All partners**: Every active partner organization can discover and enroll. - **Specific partners**: Only the partner organizations you select. Use **Search partners** to find and add them. 3. Click **Save sharing**. ![Sharing options with Private, All partners, and Specific partners](images/share-and-monitor-partner-training-cours-2.png) ### You Can Only Share With Active Partners **Specific partners** accepts active partner organizations only. Inactive, suggested, and pending organizations are refused — an organization you invited but that hasn't accepted yet can't be given a course. Sharing is all or nothing: if one organization in your selection isn't an active partner, the whole save is refused rather than going through for the others. Fours names the organizations it rejected, so remove those and save again. :::tip If a partner you expected to find isn't selectable, check their status in **All Partners** first. A `PENDING` partner becomes shareable the moment they accept your invitation. ::: ## Assign a Course to Your Own Team Courses shared *with* you can be pushed to your colleagues rather than waiting for them to find it. 1. Open the course and click **Assign to team**. 2. Search the member list and tick everyone who should take it. 3. Click **Assign**. Re-assigning is safe — people already enrolled are skipped rather than reset. :::info The member list only shows people whose email address is on **your organization's email domain**. This is deliberate: it keeps a partner's course assignments inside their own company. It applies to contact and assignee dropdowns across PRM, not just this one. If the list comes back empty with *"No members match your organization's email domain"*, the members exist but none of their addresses match. Note that subdomains and secondary corporate domains don't count as matches. ::: ## Monitor Course Progress ### Get a Quick Overview Across All Courses 1. Go to **Fours Console**, then **Partners**. 2. Click **Training**, then go to the **Partner Progress** tab. 3. Switch between **By partner**, **By course**, or **By person**. Each learner shows a progress bar and status: `Not Started`, `In Progress`, `Completed`, or `Failed` — or, on a course hosted in your own LMS, `Opened` (see the note below). Above the table, four tiles sum up your whole program. They count partner learners only; your own team's enrollments are left out. | Tile | What it counts | | --- | --- | | **Partners training** | Partners with at least one enrollment. | | **Enrollments** | Partner enrollments across your published courses. | | **Completions** | Those enrollments that are finished, with the share of all enrollments they make up. | | **Published courses** | Your published courses, noting when they include external-LMS courses. | If you publish external-LMS courses and completion sync is off, a warning under the tiles reads **Completions from your external LMS are not being read back.** Until you turn it on, those courses count zero completions here, whether or not learners have finished them. The warning's **Set up completion sync** link opens **Partners → Settings → Training / LMS**. :::note **A course hosted in your own LMS never reports a percentage.** It reads `Not Started` until a learner opens it, then `Opened`. With [completion sync](/prm/connect-an-external-lms/#completion-sync) on, it reads `Completed` once your LMS reports that the learner finished. Fours never sees the progress in between, because the lessons run in your LMS. ::: ![Partner Progress tab with By partner, By course, and By person views](images/share-and-monitor-partner-training-cours-3.png) ### Check Detail for One Course 1. Go to **Fours Console**, then **Partners**. 2. Click **Training**. 3. Open the course from the **My Courses** tab. 4. Click **Enrollments** in the top toolbar. 5. Review **Team progress**, grouped by partner organization. Each learner shows a progress bar and status (`Completed`, `In progress`, or `Not started`). ![Enrollments view showing Team progress grouped by partner organization](images/share-and-monitor-partner-training-cours-4.png) --- Source: https://doc.fours.com/prm/take-training-course/ # Take a Partner Training Course When a partner shares training with your organization, it shows up in your **Training** tab. Use it to get your team up to speed on positioning, pricing, or product knowledge, without waiting on a live session. --- ## Overview Partners can publish training courses to the organizations they work with. Those shared courses appear in your Partners Console under **Training** → **From Partners**, where you can start a course yourself, assign it to specific teammates, and work through the lessons at your own pace. If a course awards a certificate, your team earns it by completing every lesson. ## Enroll in a Course ### Step 1: Find the shared course 1. Go to **Partners Console** → **Training** → **From Partners**. 2. Use **Search courses** or browse the cards to find the one you need. 3. Check the completion badge on a card before opening it. If it's already marked done, your team may not need to retake it. ![Training tab showing courses shared from partners](images/take-a-partner-training-course-1.png) ### Step 2: Take or assign the course Open the course card, then choose one of the following. #### Option 1: Start it yourself Click **Start course**. If you've already completed it, this button reads **View my results** instead. Click it to jump back into your progress rather than restarting. **On a course hosted in the seller's own LMS**, the button reads **Open in *{LMS name}*** instead, and it reads that at every stage — before you start, partway through, and after you finish. There is no Start / Resume / Review progression because the lessons run in the seller's system, not in Fours, so there is nothing here to resume. Your progress lives in the LMS. ![Course card with the Start course button](images/take-a-partner-training-course-2.png) #### Option 2: Assign it to your team Use this if you want specific teammates trained rather than doing it yourself. 1. Click **Assign**. ![Assign button on the course card](images/take-a-partner-training-course-3.png) 2. Search for teammates by name or email. 3. Select everyone who needs the course. 4. Click **Assign**. ![Assign course dialog with teammate selection](images/take-a-partner-training-course-4.png) ## Complete a Course :::info If the course awards a certificate, it stays locked until every lesson is marked complete. ::: 1. Work through lessons in order using the left sidebar. 2. Click **Mark complete & continue** after each lesson to save your progress and move forward. 3. Check the progress bar at the top of the sidebar any time you want to see how much is left. ![Course lesson view with the sidebar progress bar and Mark complete & continue button](images/take-a-partner-training-course-5.png) ## Next Steps Once your team starts earning certificates, learn how to check status in [View your team's earned certificates](/prm/view-certificates/). --- Source: https://doc.fours.com/prm/view-certificates/ # View Your Team's Earned Certificates Review the certificates your team has earned from completed training courses, check whether each one is active or expiring, and download a copy when you need it. --- ## Overview The **Certificates** page shows all certificates earned from completed training courses. Use it to see at a glance whether a certificate is active, expiring soon, or expired, and to print or save a copy for your records. ## Find a Certificate 1. Go to **Partners Console**, then **Training**, then **Certificates**. 2. Scan the **Active**, **Expires Soon**, and **Expired** counters at the top first. These tell you at a glance whether anything needs attention before you dig into the full list. They count your team's current certificates, so a certificate that has been renewed counts once, under its newest copy. 3. Narrow the list using **Search**, or filter by certificate, issuer, or status. ![Certificates page with Active, Expires Soon, and Expired counters and the certificate list](images/view-your-team-s-earned-certificates-1.png) ## View or Print a Certificate 1. Go to **Partners Console**, then **Training**, then **Certificates**. 2. Click the certificate name. 3. Click **Print** to save a PDF copy. ![Certificate detail view with the Print option](images/view-your-team-s-earned-certificates-2.png) ## Next Steps Haven't enrolled your team yet? Start with [Take a Partner Training Course](/prm/take-training-course/). --- Source: https://doc.fours.com/prm/create-and-assign-journeys/ # Create and Assign Partner Journeys Build reusable, step-by-step playbooks that guide partners through onboarding and other key milestones, then assign them to partners and track progress from one place. --- ## Overview **Journey Templates** are reusable, step-by-step playbooks for onboarding and other key milestones in your partner program. You create the template once, assign it to partners as needed, and track progress centrally instead of managing each task by hand. :::info You'll need an Admin or Editor role to make changes here. If the fields appear locked or read-only, check your role with your Fours admin. See [Manage Users and Roles](/get-started/account/). ::: ## Create a Template 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Journey Templates**. 3. Click **+ New Journey Templates**. ![New Journey Templates button on the Journey Templates settings page](images/create-and-assign-partner-journeys-1.png) 4. Fill in the journey template details: - **Name** — What the template is called, for example "Partner Onboarding." - **Description** — A short description of what this journey is for. - **Estimated days to complete** — A rough duration estimate, shown later as a reference (for example "~5 days") wherever this template appears. - **Status** — **Draft** while you're still building it, or **Active** once it's ready to be assigned. Only Active templates make sense to assign to real partners. - **Tier outcome (Journey → Tier)** — Optional. If set to something like "Promote to Gold," completing this journey automatically promotes the partner to that tier, subject to that tier's own auto-advance setting. Leave this as "No tier outcome" if this journey isn't meant to affect tier standing. - **Sequential mode** — Toggle on if steps must be completed in order, with later steps locked until earlier ones are done. Toggle off if partners can complete steps in any order. ![Journey template creation form with name, description, estimated days, status, tier outcome, and sequential mode fields](images/create-and-assign-partner-journeys-2.png) 5. Click **+ Add step** to add each milestone to the journey. For every step, you'll set: - **Step type** — What kind of action this is: - **Sign agreement** — A step where the partner needs to sign a contract or NDA, like "Sign NDA & Partner Agreement." - **Upload document** — A step where the partner submits a file, like partner documentation you need on record. - **Complete course** — A step tied to training content, like an onboarding course. - **Earn certification** — A step tied to a certification requirement. - **Register a deal** — A step where the partner's first deal registration counts as completion. - **Custom task** — The catch-all. You can optionally link this step to a **Task**. - **Title shown to partner** — The label the partner actually sees for this step. - **Internal notes** — Notes for your own team, not visible to the partner. - **Task template** — Optionally link this step to an existing task template, if one applies. - **Required or Optional** — Whether this step must be completed to finish the journey, or whether it's a nice-to-have. - **Due date** — Either "No due date" or "Relative to start" (due some number of days after the journey is assigned). 6. Use the **up/down arrows** or drag handle to reorder steps, and the **trash icon** to remove one. Add as many steps as the journey needs, then click **Save template**. ![Journey step editor showing step type, partner-facing title, internal notes, required toggle, and due date](images/create-and-assign-partner-journeys-3.png) ### Define the Task Inside a Custom Task Step A **Custom task** step doesn't have to point at a task template you built earlier. Two tabs let you decide: - **Create new task** — write the task here, inside the step. - **Select template** — pick an existing task template from the **Task template** dropdown. Choosing **Create new task** gives you three extra fields: | Field | What it does | | --- | --- | | **Priority** | `URGENT`, `HIGH`, `NORMAL`, or `LOW`. Drives how the task sorts on the Tasks page. | | **Auto-assign by role** | Picks the assignee by role rather than by name, so the same template works for every partner. | | **Tags** | Free-form labels for filtering later. | Whichever tab you use, a task is created and linked to each partner at the moment the journey is assigned. Its title and due date come from the step above, so you don't set them twice. #### Auto-assign by role **Auto-assign by role** offers **None** plus two roles: | Role | Resolves to | | --- | --- | | **Partner Manager (internal)** | The partner manager on your side of the relationship. | | **Champion contact** | The partner's champion contact. | Resolution happens per partner when the journey is assigned, which is the point — one template, correctly assigned across every partner you give it to. :::info If Fours can't find anyone matching the role for a given partner, the task is still created but arrives unassigned, carrying an amber **No matching contact** chip. Assign it by hand, or fill in the missing contact on the partner record so the next assignment resolves. ::: ## Assign a Journey Automatically to Every New Partner A **Default onboarding template** picker sits above the template list. Choose one, and that journey is assigned the moment a partnership becomes **Active** — the partner starts onboarding without anyone remembering to assign it. Only **Active** templates can be the default, so only those are offered in the picker. Choosing **none** leaves the manual flow below exactly as it was. Two things make an auto-assignment legible rather than mysterious: - The template list shows the chosen one as **Default — auto-assigned**, and each template's usage reads as an `(n manual, n auto-assigned)` split, so you can tell deliberate assignments from automatic ones. - When a partnership is approved, the partner record shows a banner naming the journey that was auto-assigned and saying it is this organization's default onboarding template for new partners. ## Assign a Journey to a Partner Once your template is **Active**, you can assign it to partners from several places in Fours. ### From the Journey Template 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Journey Templates**. 3. Find the template, and click **Assign**. 4. In the **Assign a Journey** dialog, select the partner from the dropdown. 5. Click **Assign**. ![Assign a Journey dialog opened from a journey template with a partner dropdown](images/create-and-assign-partner-journeys-4.png) ### From the Journeys Page 1. Go to **Fours Console**, then **Partners**. 2. Go to the **Journeys** menu, and click **+ Assign Journey**. 3. In the **Assign a Journey** dialog, select the **Journey template** and **Partner** from the dropdowns. 4. Click **Assign**. ![Assign a Journey dialog on the Journeys page with journey template and partner dropdowns](images/create-and-assign-partner-journeys-5.png) ### From a Partner's Profile 1. Go to **Fours Console**, then **Partners**. 2. Click the partner's name to open their profile. 3. Click **Journeys**, then **+ Assign Journey**. 4. In the **Assign a Journey** dialog, select the **Journey template**, then click **Assign**. ![Assign a Journey dialog on a partner's Journeys tab with a journey template dropdown](images/create-and-assign-partner-journeys-6.png) ### Assign to Several Partners at Once The partner field in **Assign a Journey** takes more than one partner. Onboarding a cohort is one action, not one per company. Tick every partner who should get the journey. The confirm button counts what you selected — **Assign** for one, **Assign to 6 partners** for six — so you can check the number before committing. Partners who already have an active assignment of that same journey are **greyed out and can't be selected**, and a line under the picker tells you how many were excluded and why. This stops you accidentally issuing a second copy of a journey somebody is already halfway through. Select-all skips them too. :::tip To push template changes to partners who already have the journey, don't re-assign it — use **Reassign** on their journey card instead. See [Track Journey Progress](/prm/track-journey-progress/). ::: ## Reference: Journey Statuses **Template status** — whether a template can be handed out: | Status | Meaning | | --- | --- | | `DRAFT` | Editable, not assignable. | | `ACTIVE` | Published and assignable. | You can move a template back from `ACTIVE` to `DRAFT` to take it out of circulation while you rework it. **Assignment status** — one partner's copy of a journey: | Status | Meaning | | --- | --- | | `ACTIVE` | In progress. | | `COMPLETED` | Every required step is done. | | `ARCHIVED` | Retired from the active view. | **Step status** — visible to the partner as well as to you: | Status | Meaning | | --- | --- | | `NOT_STARTED` | Nothing has happened yet. | | `IN_PROGRESS` | Underway. | | `DONE` | Complete. | **Step types** — the six kinds of milestone a template can contain: | Type | Completed by | | --- | --- | | `SIGN_AGREEMENT` | The partner signing an agreement. | | `COMPLETE_COURSE` | The partner finishing a specific course. | | `EARN_CERTIFICATION` | The partner earning a specific certificate. | | `REGISTER_DEAL` | The partner registering their target number of co-sells. | | `UPLOAD_DOCUMENT` | The partner uploading a file. | | `CUSTOM_TASK` | Anything else — either a task template or a task you write inline. | **Task status** — for the tasks a `CUSTOM_TASK` step creates: | Status | Meaning | | --- | --- | | `OPEN` | Not started. | | `IN_PROGRESS` | Being worked on. | | `BLOCKED` | Stopped, waiting on something else. | | `COMPLETED` | Done. | **Task priority**, highest first: `URGENT`, `HIGH`, `NORMAL`, `LOW`. ## Next Steps Once assigned, see [Track Journey Progress](/prm/track-journey-progress/) to check on progress and understand what the partner sees on their end. --- Source: https://doc.fours.com/prm/track-journey-progress/ # Track Journey Progress Once a journey is assigned to a partner, use it to track where they stand, mark steps complete as they finish them, and manage the journey itself over time. --- ## Overview A **Journey** is a set of steps a partner works through, such as signing an agreement or completing training, built from a Journey Template. This page covers checking a partner's progress, marking steps complete, and managing a journey once it's assigned. :::info If you need to create a journey first, see [Create and Assign Partner Journeys](/prm/create-and-assign-journeys/). ::: ## How Steps Get Completed Steps complete two ways: Fours ticks them for you when the underlying action happens, or you tick them by hand. ```d2 direction: down group: "What the partner does" { sign: "Reaches a fully executed\nagreement" { shape: rectangle } course: "Completes the course\nthe step names" { shape: rectangle } cert: "Earns the certificate\nthe step names" { shape: rectangle } upload: "Uploads a file you\ncan see" { shape: rectangle } deal: "Gets a Fours co-sell to\nActive or beyond" { shape: rectangle } tell: "Tells you the work\nis finished" { shape: rectangle; style.stroke-dash: 3 } } auto: "Fours marks the step DONE\ncompleted by the system" { shape: rectangle } lock: "Sequential mode on,\nearlier steps unfinished?" { shape: diamond } manual: "You tick the checkbox on\nthe partner's journey card" { shape: rectangle } blocked: "Checkbox stays locked\nuntil the steps before it are done" { shape: rectangle; style.stroke-dash: 3 } done: "Step is DONE" { shape: rectangle } group.sign -> auto: "SIGN_AGREEMENT" group.course -> auto: "COMPLETE_COURSE" group.cert -> auto: "EARN_CERTIFICATION" group.upload -> auto: "UPLOAD_DOCUMENT" group.deal -> auto: "REGISTER_DEAL" group.tell -> lock: "CUSTOM_TASK" lock -> blocked: "yes" lock -> manual: "no" manual -> done auto -> done: "lands in whatever order it arrives —\nthe sequential lock gates manual ticking only" ``` ### Steps That Complete Themselves When a partner actually does the thing a step describes, Fours marks that step done — you don't have to notice and confirm it. Five actions trigger this: | The partner... | Completes a step of type | | --- | --- | | Reaches a fully executed agreement | `SIGN_AGREEMENT` | | Completes the course the step names | `COMPLETE_COURSE` | | Earns the certificate the step names | `EARN_CERTIFICATION` | | Uploads a file | `UPLOAD_DOCUMENT` | | Has a Fours co-sell reach Active or beyond | `REGISTER_DEAL` | Two details worth knowing: - **Auto-completion ignores the sequential lock.** Sequential mode gates *manual* ticking, to stop you skipping ahead. An automatic completion records something that genuinely happened, so it lands whatever order it arrives in. - **Steps match what they name.** A step tied to a specific course or certificate completes only for *that* one. A `SIGN_AGREEMENT` step attached to a particular agreement waits for that agreement; an unattached one completes on any executed agreement. :::info `REGISTER_DEAL` counts **Fours** co-sells only, and only once they reach Active or a later stage — a draft or still-pending referral doesn't count, because the partner hasn't engaged with it yet. Cloud co-sells (AWS, Azure, GCP) aren't linked to a partnership and don't count toward this step. An `UPLOAD_DOCUMENT` step completes for the organizations that can actually *see* the file. A file the partner marks private completes nothing. ::: ### Reading a Step's Status Every step carries one of three statuses, and both you and the partner see the same one: | Status | How it looks | What it means | | --- | --- | --- | | `NOT_STARTED` | An open circle | Nothing has happened on this step yet. | | `IN_PROGRESS` | A spinner in place of the circle | Partial credit. A `REGISTER_DEAL` step asking for several co-sells sits here once the first one qualifies. | | `DONE` | A checkmark, the title struck through, and a completion date | Finished, automatically or by hand. | A step whose checkbox is locked by sequential mode is dimmed and shows a padlock in place of its status icon. That is a lock on *ticking*, not a fourth status. ### Steps You Tick Yourself `CUSTOM_TASK` steps, and anything the automatic hooks didn't catch, are marked by hand. 1. Go to **Fours Console**, then **Partners**. 2. Click **Journeys**, then the **partner's name** to open their journey card. 3. Click the checkbox next to a step to mark it done. ![Partner journey card with checkboxes next to each step](images/complete-and-track-partner-journey-progr-1.png) ### Complete Custom Task Steps Linked to a Task Steps linked to a task stay locked until the linked task itself is marked Completed. 1. Go to **Partners**, then **Tasks**. 2. Complete the task assigned to you. 3. Return to the partner's Journey card. The step's checkbox is now clickable. 4. Click the checkbox to mark the step done. ## Manage a Partner's Journey Go to **Fours Console** → **Partners** → **Journeys** → **partner's name**, then click the **...** menu on the journey card. Use the option that matches what you need: ![Journey card ... menu showing Reset progress, Archive, and Reassign options](images/complete-and-track-partner-journey-progr-2.png) | If you need to... | Use | What it does | | --- | --- | --- | | Start the journey over from the beginning | **Reset progress** | Clears all completed steps and returns the journey to its starting point. All steps become unchecked again. | | Remove a completed journey from your active view | **Archive** | Permanently archives the journey. You can still view archived journeys later by filtering **Status** → **Archived**. | | Apply changes you made to the journey template after it was assigned | **Reassign** | Updates the partner's journey assignment to reflect the latest version of the template. | ## Check Journey Progress ### Check Progress Across All Partners Go to **Fours Console** → **Partners** → **Journeys** for a single view of every partner's journey assignments. What you check depends on what you're trying to find out: - **Who needs my attention today?** Start with the summary line above the table (for example "3 active · 0 completed · 0 stalled"), then filter **All statuses** down to `Stalled`, since that's who's actually behind rather than just in progress. - **How is one journey type performing across everyone?** Use the **All templates** filter to isolate it, then scan the **Progress** column for that group. - **Where does one specific partner stand?** Use the **search bar** rather than scrolling, especially once your partner list grows. ![Journeys list with the status summary line, filters, and Progress column](images/complete-and-track-partner-journey-progr-3.png) Two columns are worth knowing regardless of what you're looking for: - **Progress** shows a bar and percentage for that row's journey. - **Tier Outcome** shows which tier completing this journey will promote the partner into. A dash means this journey isn't tied to a tier. See [Partner Tiers](/prm/partner-tiers/) for how tiers are set up. ![Journeys list showing the Progress and Tier Outcome columns](images/complete-and-track-partner-journey-progr-4.png) ### Check a Partner's Progress in Detail Go to **Fours Console** → **Partners** → **Journeys** → **partner's name**. If the partner has more than one journey assigned, each shows as its own card, stacked on the page. ![Partner detail view with multiple journey cards stacked](images/complete-and-track-partner-journey-progr-5.png) ### Read the Progress Strip A partner's active journey also appears as a strip on their record, condensed to what you usually want: - **Which journey, and whose** — a **You assigned** or **Assigned to you** badge, then *{Partner}'s Journey* (or *Your Journey* on the receiving side) and the template's name. - **Where it's going** — an **unlocks · {tier}** marker when the journey promotes the partner on completion. - **How far along** — `40% · Step 3 of 5`, with a progress bar under it. - **Who it's on, and what for** — **Waiting on partner** or **Waiting on you**, followed by the title of the step being waited on and its due date when it has one. That's the difference between a stalled journey and one where the ball is simply in their court. A **View journey** action opens the full journey from there. ![The journey strip across a partner record's banner — a "You assigned" badge, the journey name and an "unlocks · Gold" marker on the left with "40% · Step 3 of 5" on the right, a progress bar beneath, and a "Waiting on partner" line naming the outstanding step and its due date beside the View journey button](images/49-journey-progress-strip.png) ## When a Journey Finishes A completed journey doesn't vanish quietly. For **14 days** after completion, the partner's record shows a celebration line in place of the active-journey strip — *"{Partner} completed a journey"* on your side, *"Journey complete"* on theirs — naming the journey and, when the journey had a tier outcome, the tier they reached. After 14 days the line clears on its own and the space goes back to whatever is active. Nothing is lost: the completed assignment stays in the Journeys list with a `COMPLETED` status. :::info The celebration only shows when there's no active journey to display. Assign the partner their next journey and the strip switches to that one immediately. ::: --- Source: https://doc.fours.com/prm/track-partner-journey/ # Track Your Assigned Partner Journey Follow the onboarding and program journeys your seller assigns to you, read your progress at a glance, and know what's expected at each step. --- ## Overview Your seller may assign one or more journeys to guide you through onboarding or other program milestones. Each journey is a sequence of steps your seller wants you to complete. Because each seller designs their own journeys, the steps, names, and order may look different from the examples in this guide. ## Most Steps Tick Themselves You don't have to tell your seller when you've finished something. For most step types, doing the work *is* how the step gets marked done — Fours notices the underlying action and completes the step for you, usually within moments. | When you... | The step completes | | --- | --- | | Reach a fully executed agreement with your seller | **Sign agreement** | | Finish the course the step names | **Complete course** | | Earn the certificate the step names | **Earn certification** | | Upload a file your seller can see | **Upload document** | | Get a Fours co-sell with that seller to **Active** or beyond | **Register a deal** | Two things follow from that: - **You don't need to wait your turn.** If your journey runs in sequential mode, later steps show as locked — but that lock only governs manual ticking. When you actually complete the underlying work, the step is marked done whatever order it happens in. - **Steps match exactly what they name.** A step that names a specific course or certificate completes only for *that* one. A **Sign agreement** step attached to a particular agreement waits for that agreement. :::info **Custom task** steps are the exception. There is no underlying action for Fours to watch, so your seller marks those done after you tell them the work is finished. A **Register a deal** step that asks for several co-sells moves to *in progress* once your first one qualifies, and to *done* once you reach the number the step asks for. A file you upload as **private** completes nothing — no one on the seller's side can see it. ::: :::info The journey view in your portal is read-only. You can open a step to go do the work, but the checkboxes belong to the seller who assigned the journey — you never have to tick anything yourself. ::: ## Find Your Journey Go to **Partner Console**, then **Journeys**. If your seller has assigned more than one journey, each appears as its own card. ![Journeys page in the Partner Console showing assigned journey cards](images/track-your-assigned-partner-journey-1.png) ## Read Your Progress A progress bar at the top of each card (for example, "1/4 · 25%") shows how far along the journey is overall. Every step carries one of three statuses: | Status | How it looks | What it means | | --- | --- | --- | | **Not started** | An open circle | Nothing has happened on this step yet. | | **In progress** | A spinner in place of the circle | Partial credit. A **Register a deal** step reaches this once your first qualifying co-sell lands but before you've hit the number the step asks for. | | **Done** | A checkmark, with the title struck through and **Completed [date]** below it | Finished — either automatically, or ticked by your seller. | Sequential mode adds one more thing to read: a step that isn't yet eligible to be ticked is dimmed and shows a **grey padlock** in place of its status icon. That's a lock on *manual* completion, not on your progress — finishing the underlying work still completes the step. See [Most Steps Tick Themselves](#most-steps-tick-themselves). ![Journey card showing completed, open, and locked steps with a progress bar](images/track-your-assigned-partner-journey-2.png) ## Act on a Step Open a step's title to see its full detail. Where the step points at something you can go do — a course to take, an agreement to sign, a task to work, a certificate you've earned — the step offers an **Open** action that takes you straight there. If the thing a step points at is no longer available (a course withdrawn, an agreement or task removed), the step says so rather than sending you to a dead end. Contact the seller who assigned the journey. --- Source: https://doc.fours.com/prm/broadcasts/ # Send a Broadcast to Your Partners Compose one message and send it to every partner Slack channel at once — then see, partner by partner, who received it, who reacted, and who replied. Messages post under your organization's connected Slack bot. --- ## Overview **Broadcasts** let you announce something once instead of pasting it into every partner's Slack channel by hand: a product release, a pricing change, a training deadline, a webinar invite. You write the message, pick who should get it, and Fours posts it to each partner's mapped Slack channel using your organization's connected Slack bot. Broadcasts are **Slack-only**. A partner receives a broadcast only if that partner has a Slack channel mapped in Fours — partners without one are never included in an audience, and they are not shown as an option when you pick recipients. :::info Composing and sending needs an Admin or Editor role on Partners. The standard **Viewer** role has no Partner Management permissions; a [custom role](/get-started/account/#custom-role-with-granular-permissions) with only `partners.read` still sees the controls, but the send is rejected. **Broadcasts** is hidden entirely for partner-side organizations. See [Account](/get-started/account/). ::: ## Before You Start Connect your Slack workspace first. Until you do, the Broadcasts page shows a **Slack isn't connected** banner and the **Next**, **Send** and **Schedule** buttons stay disabled — the message would have nowhere to go. 1. Click **Connect Slack** on the banner, or go to **Partners → Settings → Slack**. 2. Authorize the Suger app in your Slack workspace. 3. Map a Slack channel to each partner you want to reach. ![The Broadcasts page with the "Slack isn't connected" banner — the Slack mark, the explanation that broadcasts go to partner Slack channels, a Connect Slack action on the right, and the New broadcast button greyed out above it](images/46-broadcast-slack-banner.png) :::info There is a second, milder banner: **Slack status couldn't be checked**, with a **Check Slack settings** action. It means Fours could not confirm your workspace, not that it is disconnected — so sending is **still allowed**, though delivery may fail. Only a confirmed disconnection blocks the send. ::: ## Find Broadcasts Go to **Fours Console**, then **Partners**. In the sidebar, under **Workspace**, click **Broadcasts**. The list is grouped into four tabs: | Tab | What it holds | |-----|---------------| | **Sent** | Broadcasts already delivered. The time column shows when they went out. | | **Scheduled** | Broadcasts waiting for their send time. | | **Drafts** | Saved but not sent. Drafts are the only broadcasts you can delete. | | **Failed** | Every target channel errored, or delivery retries ran out. | Each row shows the broadcast's **Name**, its **Audience**, and a time column that changes with the tab — *Sent*, *Scheduled*, or *Updated*. ![The Broadcasts list on the Sent tab — the Sent, Scheduled, Drafts and Failed tabs above a table of Name, Audience and Sent columns, with the connected Slack workspace and the New broadcast button top-right](images/31-broadcasts-list.png) ## Compose and Send a Broadcast Click **New broadcast**. The composer is three steps: **Message**, **Audience**, **Review**. ### Step 1 — Message 1. Give the broadcast an **internal name**. This is how you'll find it in the list; partners never see it. 2. Add a **Header** if you want a bold first line. It's optional. 3. Write the **Message**. The editor supports bold, italic, links, emoji, and file attachments. 4. **Send as** shows your Fours organization's name. It is read-only, and it is a label for you rather than something Slack displays — the message posts under your connected Slack bot's own identity. 5. Leave **Show link previews** on if you want Slack to unfurl links in the message, or switch it off for a cleaner post. It's on by default. A live preview beside the editor shows the message the way Slack will render it, unfurled link cards included. ![Step 1 of the composer — the internal name, optional header and rich-text message on the left, with Send as, the Show link previews toggle, and a live Slack preview of the message on the right](images/32-broadcast-compose-message.png) **Attachments.** Files are uploaded to each target channel along with the message. The limits are: | Limit | Value | |-------|-------| | Attachments per broadcast | 10 | | Size per file | 50 MB | | Total size per broadcast | 100 MB | ### Step 2 — Audience Choose who receives the broadcast: - **All partners with a mapped channel** — everyone reachable, with the count shown so you know the real reach. - **Specific partners** — a searchable picklist. Only partners with a mapped Slack channel appear in it. - **By tier** — a single tier, chosen from the tiers configured for your organization. See [Partner Tiers](/prm/partner-tiers/). :::warning Partners without a mapped Slack channel are excluded from every audience, including **All partners**. If a partner tells you they never got a broadcast, check their Slack channel mapping first. ::: If *no* partner has a channel mapped yet, this step opens with a notice — **"None of your partners have a Slack channel configured."** — and a **Go to Settings** action that saves your work as a draft and takes you to **Partners → Settings → Slack**. The notice sits above the audience choice rather than inside one option, because every option is a dead end until at least one channel exists: **All partners** resolves to nobody, the **Specific partners** picker has no entries, and a tier matches only unmapped partners. :::info The notice is advisory — it explains the situation rather than blocking you. The real guard runs when you send: a **Specific partners** or **By tier** audience that matches no reachable partner is rejected outright, rather than being accepted and quietly finishing as *Sent* with nobody on the list. **All partners** is deliberately not guarded that way, since it legitimately resolves to zero when an organization simply has no mapped channels yet. ::: ![Step 2 of the composer — the three audience options, with the reminder that only partners with a mapped Slack channel can receive a broadcast](images/33-broadcast-compose-audience.png) ### Step 3 — Review Review the recap, then decide when it goes out: - Leave the schedule time **empty** and the primary button reads **Send now**. - Fill in a **date and time** and the same button becomes **Schedule**. Times in the past are rejected inline. You can click **Save as draft** from any step and come back to it later. ![Step 3 of the composer — a recap card listing Name, Send as, Audience and Link previews, the optional "Schedule for later" datetime field below it, and Back on the left with Schedule and Send now on the right](images/44-broadcast-review.png) After an immediate send, the list refreshes on its own while delivery completes — you don't need to reload the page. ### Send a Test First Before a message goes to your whole partner list, send it to one of your own Slack channels and look at it. The live preview beside the editor is close, but a test is the real Slack render — unfurled links, attachments, and all. **Test** sits with the composer's header actions, so you can fire one from any step. It is greyed out only when Slack is disconnected; every other reason a test can't go through is explained inside the dialog rather than through a disabled button. 1. Click **Test**. The **Send a test** dialog opens on your organization's internal notifications channel — the same one co-sell internal notes go to, set under **Partners → Settings → Slack**. 2. Click **Change** (or **Pick a channel**, when no default is set) to send it somewhere else this once. 3. Click the send action in the dialog. The test arrives carrying exactly the message body a partner would receive, untouched, plus one appended line: *"Test broadcast sent by {your name} — partners did not receive this."* That line makes it impossible for a teammate reading the channel to mistake a test for the real thing, while leaving the render above it trustworthy as a proof. :::warning **A test can only go to an internal channel.** Fours refuses any channel mapped to one of your partnerships — including partners who are paused or archived, because a channel a partner can still read is still a partner channel — and any channel shared with people outside your organization through Slack Connect. It also refuses a channel the Fours Slack bot hasn't been invited to. If Fours can't confirm a destination is safe, it refuses rather than sending. On a very large partner list the dialog says so up front: it couldn't check every partnership, so the send may be refused when you submit it. ::: A test writes no broadcast and no recipient rows. Nothing appears in **Sent**, **Scheduled**, **Drafts**, or **Failed**, and no per-account delivery is recorded. | Test-send limit | Value | |-----------------|-------| | Total attachment size | 25 MB (a real broadcast allows 100 MB) | | Concurrent tests carrying attachments | 4 at a time. A fifth waits up to 5 seconds for a slot, then asks you to retry. | Text-only tests are never throttled. ## Track a Broadcast Open any sent broadcast to see how it landed. Three tiles summarize the whole send: - **Delivered** — channels the message reached. - **Reactions** — total emoji reactions across all channels. - **Replies** — total replies in the message threads. Below them, a **Per-account delivery** table breaks the same numbers down by **Account**, **Channel**, **Status**, **Reactions**, and **Replies**. Partners that were skipped for having no mapped channel are not listed. Once a broadcast has finished sending, the detail page keeps refreshing on its own, so reaction and reply counts fill in as partners engage — you don't need to reload it. ![A sent broadcast — the Delivered, Reactions and Replies tiles above the message that went out, then the Per-account delivery table with one row per partner showing its channel, delivery status, and reaction and reply counts](images/45-broadcast-detail.png) :::tip Reactions and replies are the fastest read on whether an announcement actually landed. A broadcast delivered to 30 channels with two reactions usually means the message needs a clearer ask, not a resend. ::: ## How a Broadcast Reaches a Partner ```d2 direction: right you: "You\nPartners → Workspace → Broadcasts" { shape: rectangle } compose: "Compose\nmessage · audience · schedule" { shape: rectangle } suger: "Fours" { shape: rectangle } check: "Partner has a\nmapped Slack channel?" { shape: diamond } slack: "Partner's Slack channel" { shape: rectangle } skipped: "Skipped\n(not shown in the report)" { shape: rectangle; style.stroke-dash: 3 } engagement: "Reactions and replies\nflow back to the detail page" { shape: rectangle } you -> compose compose -> suger: "Send now, or at the scheduled time" suger -> check: "for each partner in the audience" check -> slack: "yes — post as your org's bot" check -> skipped: "no" slack -> engagement { style.stroke-dash: 4 } ``` ## Reference: Broadcast Statuses **Broadcast status** — where the whole broadcast sits in its lifecycle: | Status | Meaning | |--------|---------| | `DRAFT` | Saved but not sent. The only state you can delete. | | `SCHEDULED` | Waiting for its send time. | | `SENDING` | Delivery in flight across the audience's channels. | | `SENT` | Delivery finished. | | `FAILED` | Every target channel errored, or the delivery retries ran out. | **Audience type** — how the recipient list was chosen: | Type | Meaning | |------|---------| | `ALL` | Every partner with a mapped Slack channel. | | `SPECIFIC` | The partners you picked by hand. | | `TIER` | Every partner in one tier. | **Recipient status** — the result recorded for one partner: | Status | Meaning | |--------|---------| | `SENT` | The message reached that partner's channel. | | `FAILED` | Slack rejected the post to that channel. | | `SKIPPED_NO_CHANNEL` | There was nowhere to post. Left out of the **Per-account delivery** table entirely — every audience already excludes partners with no mapped channel, so this can only mean a channel was unmapped mid-delivery. Listing it as a delivery outcome would pad the report with a partner you never chose to target. | ## Scope and Limits - **Slack only.** There is no email or in-portal equivalent of a broadcast today. - **One channel per partner.** A broadcast goes to the partner's mapped channel, not to individual partner contacts. - **Drafts are the only deletable state.** Sent and scheduled broadcasts stay in the list as a record. - **Partner-limited organizations don't see Broadcasts.** The item is hidden from the sidebar for partner-side orgs — it is a seller-side tool. - **Send as is a label, not an identity.** Slack posts every broadcast under your connected bot's own identity; the field never reaches Slack. - **A test is not a broadcast.** Tests reach only internal channels, leave no record in any tab, and cap attachments at 25 MB rather than 100 MB. --- Source: https://doc.fours.com/prm/work-a-partner-record/ # Work a Partner Record Everything you know about one partner lives on a single page: the deals in flight, what each side owes the other, the contracts, the shared events, and the onboarding still to finish. --- ## Overview The **partner record** is the page you open when you click a partner's name. It has three parts that stay put no matter which partner you're looking at: - a **banner** across the top with the partner's identity, status, and the quick actions you'd take on them, - a **Sections** rail down the left that swaps the main column between ten sections — it needs a wide window, and is hidden below roughly 1280px, - a **sidebar** on the right holding the fields you edit and the relationship context you read. :::info This page needs an **Admin** or **Editor** role — to open it at all, not only to save. A read-only (**Viewer**) role has no Partner Management access and sees an explanatory screen instead of the workspace. See [Who can use Partner Management](/prm/#who-can-use-partner-management). ::: ## Open a Partner Record 1. Go to **Fours Console**, then **Partners**. 2. On the **All Partners** tab, click the partner's name. 3. The record opens on **Overview**. Selecting a section in the rail swaps the main column — it does not scroll the page. Links from elsewhere in Fours (a journey row, a task, a Slack notice) can open the record straight onto a specific section rather than Overview. ![A partner record on the Overview section — the Sections rail on the left, direction-aware commission tiles and the At a glance cards in the main column, and the Slack, Partner Details, Cloud Account IDs and Commercial cards in the right sidebar](images/36-partner-record.png) ## The Banner and Quick Actions The banner shows your logo, the partner's logo, their name, marketplace channel badges, and a meta row with **status**, partner type, **Since** date, and the **Owner**. Three controls sit on it: | Control | What it does | |---------|--------------| | **Register a Deal** | Opens the co-sell registration flow for this partner. Appears once the partner is a linked Fours organization and partner co-sell is enabled for your org. | | **Invite to Collaborate** | Only on a partner still at status `SUGGESTED` — a company Fours found for you that you haven't contacted. | | **More Actions** | **Create CPPO**, **Register a Deal on Partner's Behalf**, **Bulk Upload Deal Registrations**, and **Timeline**. | **Register a Deal on Partner's Behalf** records a deal the partner sourced and asks them to confirm it. It appears only for partnerships you sell through — where the **Relationship Type** is **We are seller**, or is not yet set (in which case the action first asks you to set the relationship type) — and stays hidden when the partner is the seller. The partnership status must be **Active** or **Pending**. It also needs a **Partner Champion** on the record with an email address — Fours addresses the confirmation request to that person, so the action stops and tells you to nominate one if the field is empty. Above the banner, **Preview as {partner}** switches the page into the partner's outbound view: the Overview renders the template they see in their portal, and every edit control on the page goes read-only until you click **Exit preview**. See [Customize the Partner Portal Overview](/prm/customize-the-partner-overview/). ![The partner banner — both logos side by side, the partner name with its cloud badge, and a meta line carrying the partnership status, relationship type, start date and owner, with More Actions on the right](images/39-partner-banner.png) ## The Sections Rail The rail lists the sections in this order: | Section | What it holds | |---------|---------------| | **Overview** | Active journeys, then the cards from the Overview template — commissions, at-a-glance metrics, an AI partner summary, revenue by channel, deals over time, and activity. See [The Overview Numbers](#the-overview-numbers). | | **Co-Sell** | The **Co-Sells** list, newest first and split into pages: opportunity name, customer, stage, target close date, **My Deal Role**, additional partners, and partner acceptance. **Search co-sells** matches the opportunity name, the customer, and the stage across every page, not only the one on screen. | | **Commissions** | The commission ledger for this partnership. See below. | | **Marketplace** | **CPPO Activity** — private offers matched to this partner by buyer ID or marketplace seller ID. | | **Journeys** | Journeys assigned to this partner and their step progress. | | **Tasks** | Action items on this relationship, in both directions. | | **Resources** | Files shared with the partner and received from them, split **All / Shared / Received**, each with a count. **Shared** lists your files shared with all partners or with this partner. **Received** lists the partner's files shared with you, plus files they share with all partners while your partnership is `ACTIVE`. **All** combines the two. | | **Events** | Webinars, training sessions, and meetups shared between you. See below. | | **Training** | Courses you've shared with this partner and courses they've shared with you. | | **Agreements** | NDAs, MSAs, referral agreements, and SOWs. See below. | :::tip **Marketplace** is where this partner's CPPO transactions live. ::: Not every partner shows all ten: - A partner who **hasn't accepted your invitation yet** (status `PENDING`) shows only **Overview**, **Co-Sell**, **Commissions** (when commission tracking is enabled), **Marketplace**, and **Agreements**, under a banner explaining why. Those are your own records about the company and are real before anyone replies — a contract can predate the invitation; the rest depend on a partnership being in force. - **Tasks** and **Resources** need the partner to be a linked Fours organization — both address the partner's own org directly. - **Training** needs a linked organization *and* status `ACTIVE`, because that is the only state in which courses are shared across a partnership. - **Commissions** appears when commission tracking is enabled for your organization. ## The Sidebar | Card | What's in it | |------|--------------| | **Slack** | The Slack channel mapped to this partner, with its connection status. Read-only — mapping happens in **Partners → Settings → Slack**. | | **Tier** | Their tier in your program (editable via the dropdown), and, when the partner runs their own program, your tier in theirs (read-only — they own it). The card only appears when the partnership's **Relationship Type** puts a tier program in play *and* that program has a tier to show — so it's absent while Relationship Type is unset, and while you're the seller but haven't defined any tiers yet. See [Partner Tiers](/prm/partner-tiers/). | | **Partner Details** | **Partner Manager**, **Engagement Type**, **Relationship Type**, **Location**, **CRM Account**, **Partner Champion**, and **Cloud Account IDs**. **Engagement Type** and **CRM Account** are seller-side fields: a partner organization on the free partner-limited plan doesn't see them at all. | | **Commercial** | The **Commission Plan** applied to this partner. See [Set Up and Manage Commission Plans](/prm/commission-plans/). | | **Relationship Hub** | Three tabs: **Contacts** (every contact on the linked CRM account), **Inbox** (recent email with this partner's domain), and **Gong**. | **Cloud Account IDs** — the AWS, GCP, and Azure account IDs used to auto-match CPPO transactions to this partnership — is a sub-section inside **Partner Details** rather than a card of its own. There is no separate **Partner Type** field; **Engagement Type** is the one that classifies the partner. **Partner Manager** and **Partner Champion** are searchable — type to filter by name or email rather than scrolling the list. **Partner Champion** options come from the linked **CRM Account**'s contacts, so the field reads **Connect CRM account first** until you link an account. Once it's linked, the list holds every contact on that Salesforce or HubSpot account, sorted by name, and you can also search by job title. - The current champion stays pinned at the top with a star, even if they've left the account; then the row reads *No longer on {account}*. - **None** clears the champion. - The bottom of the list confirms what was loaded: *All N contacts loaded from {account}*, or *No contacts on {account}*. - If the contacts can't be loaded, the field says *Couldn't load CRM contacts*. You can still keep the current champion or choose **None**. :::info **Gong** is a placeholder. The tab renders "Gong integration coming soon", but the integration is **not available as of August 2026 and no release date is committed**. Call activity cannot be synchronized into a partner record today — track calls in Gong itself, and use **Notes** on the partner record for anything the partner team needs to see in Fours. ::: ![The partner record's right sidebar — the Slack card, Partner Details with the partner manager, engagement and relationship type, location, CRM account and champion, the inline Cloud Account IDs fields, and the Commercial card. This partnership has no tier program, so no Tier card appears](images/40-partner-sidebar.png) ### Engagement Type **Engagement Type** names the motion this partner runs. Pick from: | Option | Use it for | | --- | --- | | **Reseller** | Moves your licence transactionally under their own agreement. | | **Value Added Reseller** | Resells, and bundles their own integration or services with it. | | **Referral Partner** | Passes you leads for a fee rather than transacting. | | **Systems Integrator** | Builds and delivers the implementation around your product. | | **MSP (Managed Service Provider)** | Runs your product on an end customer's behalf as a managed service. | | **Technology Partner** | Integrates with you at the product level. | | **Agency** | Sells or services on your behalf as a marketing or services agency. | | **Distributor** | Sells through a downstream network rather than direct. | | **Affiliate** | Drives referrals at arm's length, usually at volume. | **Reseller** and **Value Added Reseller** sit next to each other deliberately: they are two distinct resale motions, and the difference is worth deciding at the moment you choose. Resellers Fours discovers from your marketplace transactions are created as **Reseller** — change it if the relationship is really value-added. The same nine options appear as the **Partner Type** column of a bulk CSV invitation, so a partner's type can be set before they ever accept. See [Invite Partners](/prm/invite-partners/). ## The Overview Numbers The Overview's numbers — the **At a glance** tiles and the **Revenue by Channel** and **Deals Over Time** charts — each carry an ⓘ. Hover over it, or tab to it, to see exactly what the number counts. The definitions read the same for you and your partner, and "you" is always whoever is looking. | Figure | What it counts | |--------|----------------| | **Total Revenue** (At a glance) | Marketplace revenue already disbursed on the deals behind this partnership's private offers, across all channels, all time. Deals booked but not yet disbursed aren't included. | | **Total Deals** (At a glance) | Co-sell deals with this partner, all time, in any status except drafts. | | **Avg. Deal Size** (At a glance) | The average value of the deals in **Total Deals** that have a deal value in US dollars, open or closed. | | **Revenue by Channel** | Disbursed revenue split by marketplace channel. The slices add up to **Total Revenue**. | | **Deals Over Time** | Co-sell deals with this partner, counted by the quarter they were created in. | **Total Deals** counts co-sell deals only. Private offers transacted with the partner aren't included — they're in the **Marketplace** section. A deal shared with several partners counts once on each of their records, and a deal whose value has been hidden from you is left out of **Avg. Deal Size**. ### When the Deal Figures Update **Total Deals**, **Avg. Deal Size**, and **Deals Over Time** are recalculated every hour, so a co-sell registered or changed in the last hour may not be counted yet. To recalculate now, click the refresh icon in the **At a glance** header, whose hover text reads *"Co-sell deals are recalculated hourly. Click to recalculate now."* Anyone who can open the partner record can use it. ```d2 direction: right deals: "Co-sell deals registered\nor changed with this partner" { shape: rectangle } hourly: "Recalculated\nevery hour" { shape: rectangle } now: "Refresh icon in\nAt a glance" { shape: rectangle } tiles: "Total Deals · Avg. Deal Size\nDeals Over Time" { shape: rectangle } deals -> hourly -> tiles now -> tiles: "recalculate now" ``` ## Commissions ### The tiles read by direction The tiles at the top of the section name **who owes whom**, because "payable" and "receivable" only mean something if you already know which side of the deal you're on. Fours works the direction out from the commission activity on the record, not from a setting: | Commission moves… | Tiles shown | |-------------------|-------------| | From you to the partner | **You owe** · **Paid so far** | | From the partner to you | **{Partner} owes** · **Paid so far** | | Both ways | **You owe** · **{Partner} owes** · **Paid so far (by you)** · **Paid so far (by {Partner})** | A one-way relationship shows two tiles; a two-way one shows four, and the settled tiles are qualified by payer so the pairs can't be confused. Each tile's ⓘ gives its definition: the *owes* tiles count commissions earned and not yet paid, and the *Paid so far* tiles count everything already paid, all time. When a partnership carries commissions in more than one currency, the tiles show the **leading currency only** — the one with the largest total — and a **+N other currencies** note sits beside them. Hover it to see the same tiles broken out per currency. ![The Commissions section on a two-way partnership — four tiles reading You owe, Paid so far (by you), Acme Corp owes and Paid so far (by Acme Corp), above the Type, Direction and Currency filters and a ledger showing both directions](images/37-partner-commissions.png) ### Narrowing the ledger A filter bar sits above the records table: | Control | Values | |---------|--------| | Search | Matches the deal name, type, and status. | | **Type** | **All**, plus **Co-Sell**, **CPPO**, and **Direct Resell** — only the types actually present in this partner's ledger are offered. | | **Direction** | **All** · **You pay** · **You receive** | | **Currency** | **All**, plus each currency in the summary. | | **Reset** | Clears all three dropdowns. Disabled when none are set. | Under the bar, three tabs split the rows: **All**, **Pending**, and **Completed**, each with a count that follows the active filters. The table itself shows **Deal**, **Type**, **Direction**, **Deal value**, **Rate**, **Commission**, **Status**, and **Close date**. Status is one of **Calculated**, **Paid**, **Realized**, **Reversed**, or **Clawback pending**. :::info The ledger is read-only here — direction, status, and the totals are all computed for you. Rates and splits come from the commission plan on the **Commercial** card; see [Set Up and Manage Commission Plans](/prm/commission-plans/) to change them. ::: The three dropdown filters are per-partner and clear when you open a different partner, so one partner's selection can never silently hide another partner's rows. ## Agreements Agreements are contract records attached to the partnership. Click **Add Agreement**, then give it a **Name**, a **Type**, an optional **Status**, and optional **Effective Date** and **Expiry Date**. Clicking the name opens the agreement to edit the metadata and attach files. | Type | Shown as | |------|----------| | `NDA` | NDA | | `MSA` | MSA | | `REFERRAL_AGREEMENT` | Referral Agreement | | `SOW` | SOW | | `OTHER` | Other | | Status | Shown as | |--------|----------| | `DRAFT` | Draft | | `AWAITING_SIGNATURE` | Awaiting Signature | | `PARTIALLY_SIGNED` | Partially Signed | | `FULLY_EXECUTED` | Fully Executed | | `EXPIRED` | Expired | :::warning **Fours does not detect signatures.** It never moves an agreement to Fully Executed on its own — not when a file is attached, not when a partner signs elsewhere. Whoever owns the contract updates the status by hand. The one thing Fours does set for you is the *starting* status. Assigning a journey whose template has a **Sign agreement** step creates that agreement on the partnership automatically, already at **Awaiting Signature**, with the step's due date as the expiry date and any template document attached in the **Template** role. From there the status is yours to move like any other. ::: Each file you attach carries a role: **Template**, **Signed by Party A**, **Countersigned**, **Final Executed**, or **Amendment**. Agreement attachments live with the agreement and never appear in the general partner file library. ![The Agreements section — Agreement Name, Type, Status, Effective Date and Expiry Date columns showing fully executed, awaiting-signature and draft agreements, with the Add Agreement button](images/38-partner-agreements.png) ## Events The Events section shows only what's shared **between** you and this partner: events you shared with them, and events they shared with you. Three tabs split them: **All**, **Shared** (created by you), and **Received** (created by the partner). Alongside the tabs are a search box, an **All types** filter, and a switcher between list and calendar view. Click **New Event** to create one. It opens pre-scoped to this partner. | Field | Notes | |-------|-------| | **Title** | Required. | | **Type** | **Webinar / Online Session**, **Certification / Training Session**, **In-Person / Field Event**, or **General Calendar Event**. | | **Description** | Optional. | | **Date** | Required. | | **Start** / **End** / **Timezone** | Timezone is one of ET, CT, MT, PT, or UTC. Times are authored in that zone, so the event reads the same for every viewer. | | **Meeting URL** or **Address** | The label follows the type — webinars and training take a URL, in-person and general events take an address. | | **Capacity** | Optional. Blank means unlimited. | | **RSVP** | On by default. | | **Share with** | **All partners**, **Specific partners**, or **Partners by tier**. | Only **ACTIVE** partners appear in the **Specific partners** picker, and **Partners by tier** draws on the tiers you configured in [Partner Tiers](/prm/partner-tiers/). :::info Partners on a partner-limited plan don't see the All / Shared / Received tabs at all — they only ever receive events, so there's no split to show them. ::: ![The Events section on a partner record — All, Shared and Received tabs above events shared with and received from this partner, with the type filter and the List/Calendar switcher](images/41-partner-record-events.png) ## Table Conventions The tables across Partner Management share three habits: - **An Actions column.** Per-row actions live behind a kebab menu in a trailing **Actions** column rather than as inline buttons. Destructive items are red, and an unavailable one explains why underneath its label. - **A Columns chooser on the list pages.** The standalone list tables — All Partners, Journeys, Tasks, Training, Certificates, and the **Events** page — have a **Columns** control for picking which columns to show, and your choice is remembered in your browser. It's a list-page convention, not a partner-record one: the sections on this page, the **Events** section included, have no Columns control. - **Filters and sorting that stick.** Sorting and page size persist per table between visits. The exception is the Commissions filter bar on this page, which is deliberately per-partner and resets when you open a different partner. ## How a Partner Record Fills In ```d2 direction: right invite: "You invite a company\nPartners → Invite" { shape: rectangle } pending: "Partnership PENDING\ninvitation unanswered" { shape: rectangle style.stroke-dash: 3 } early: "Visible now\nOverview · Co-Sell · Marketplace\nAgreements: NDA · MSA · SOW · referral\nCommissions, when commission tracking is on" { shape: rectangle } active: "Partnership ACTIVE\ninvitation accepted" { shape: rectangle } journeys: "Journeys\nassigned onboarding playbooks" { shape: rectangle } tasks: "Tasks + Resources\nneeds a linked Fours org" { shape: rectangle } training: "Training\nneeds ACTIVE + a linked org" { shape: rectangle } events: "Events\nshared and received" { shape: rectangle } invite -> pending pending -> early: "your own records about the company" pending -> active: "partner accepts" active -> journeys active -> tasks active -> training active -> events ``` ## Where Each Section Is Documented This page maps the screen. The work inside each section has its own guide: - [Create and Assign Partner Journeys](/prm/create-and-assign-journeys/) and [Track Journey Progress](/prm/track-journey-progress/) — building and running the journeys shown in the **Journeys** section. - [Set Up and Manage Commission Plans](/prm/commission-plans/) — the plans that produce the numbers in **Commissions**. - [Partner Tiers](/prm/partner-tiers/) — the tiers on the sidebar **Tier** card and behind by-tier event sharing. - [Set Your File Sharing Defaults](/prm/file-sharing-defaults/) — the defaults that decide what lands in **Resources**. - [Build a Partner Training Course](/prm/build-a-training-course/) — authoring the courses that appear under **Training**. - [Customize the Partner Portal Overview](/prm/customize-the-partner-overview/) — designing what the partner sees on their own Overview. --- Source: https://doc.fours.com/prm/customize-the-partner-overview/ # Customize the Partner Portal Overview Branding changes how your partner portal looks. **Partner Views** changes what's actually on it — which cards a partner lands on, in what order, and what you have to say to them. And because the other side can do the same to you, it also changes what you land on. --- ## Overview By default every partner opens their portal Overview onto the same standard set of cards. **Partner Views** lets you replace that with a layout you design: reorder the built-in cards, hide the ones that don't apply, and add your own content — a welcome note, a price list, a gallery of assets. It has two halves: - **Content** — a library of reusable content you author once: rich text, tables, and media galleries. - **Templates** — reusable Overview layouts. Each template is a grid of blocks; a block is either a built-in Fours card or a pointer at one of your content items. You then apply a template to specific partners. The arrangement is symmetrical, which is easy to miss. A template you author and assign is your **outbound** view — what that partner sees from you. When the partner is a Fours organization running their own program, they can assign you one too, and that **inbound** template is what you see: opening a partner record lands on their layout for you, resolved from their library, and **Preview as {partner}** is the button that flips to your outbound side. If the partner has customized nothing, the inbound view falls back to the standard Overview cards, drawn with your real relationship data. :::info Customizing the partner overview needs an **Admin** or **Editor** role — to open the editor at all, not only to save. A read-only (**Viewer**) role has no Partner Management access. See [Who can use Partner Management](/prm/#who-can-use-partner-management). **Partner Views** itself is a seller-side tool and does not appear for partner organizations. If it's missing from the settings rail, that's your organization's type — not your role. See [Account](/get-started/account/). ::: ## Find Partner Views 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Partner Views**. 3. Use the **Content** and **Templates** sub-tabs. ![Settings → Partner → Partner Views — the Content and Templates sub-tabs, the New content button, and the three reusable content types: Rich Text, Table and Media Gallery](images/44-partner-views-content.png) ## Step 1 — Author Your Content The **Content** tab holds the material your blocks will point at. Click **New content** and pick a kind: | Kind | Use it for | |------|------------| | **Rich Text** | A welcome message, program rules, an announcement. Formatted in a WYSIWYG editor. | | **Table** | Price lists, contact directories, SLA tiers — anything with columns and rows you type yourself. | | **Media Gallery** | Logos, screenshots, and other assets. Upload each image, give it a caption, and choose a **Tile** or **Waterfall** layout and how many show per page. **PNG, JPG and GIF only.** | Each item gets a **Name** — that name is the heading a partner sees above the block — and its own content editor. Content is grouped on the page by kind, with a count and the date each item was last updated. :::warning Deleting a content item doesn't delete the blocks pointing at it. Those blocks render nothing until you repoint them at something else. ::: :::info **Media Gallery accepts PNG, JPG and GIF, and nothing else.** Gallery images are stored as real files rather than embedded in the page, and those are the formats the file store accepts. Pick anything else — a `.webp` or a `.heic`, both very common straight off a phone — and you get *"PNG, JPG and GIF images only"* instead of a picture. The check runs on drag-and-drop too, not just the file picker. ::: ![The New content menu open, offering Rich Text, Table and Media Gallery](images/45-new-content-menu.png) ## Step 2 — Build a Template On the **Templates** tab, each template card shows its name, a **Default** badge if it's the org default, how many partners use it, and how many blocks it holds. Click **New template** to start from the standard layout, or the copy icon on an existing one to **clone** it. **Edit** opens a full-page editor. ### The canvas The toolbar carries the template **name**, a **Columns** control set to **1**, **2**, or **4**, a **Preview** toggle, **Discard**, and **Publish**. Your layout changes aren't saved until you click **Publish** — **Discard** drops them and returns to the list. :::tip **New template** and **clone** both create the template straight away, before you've edited anything. If you change your mind in the editor, discard your edits and then delete the template from the Templates tab. ::: The left panel is the component palette, in two groups. Drag an item onto the canvas to add it. **Built-in cards** draw live Fours data about the partnership — the editor shows sample data in their place: | Block | Shows | |-------|-------| | **Commissions** | What each side owes the other. | | **At a Glance** | Total Revenue, Total Deals, and Avg. Deal Size. See [what each one counts](/prm/work-a-partner-record/#the-overview-numbers). | | **Partner Overview (AI)** | An AI-written summary of the partner. | | **Revenue by Channel** | Disbursed revenue split across marketplace channels. | | **Deals Over Time** | Co-sell deals, counted by the quarter they were created in. | | **Activity & Engagement** | A strip of relationship facts — Partnership Since, Last Active, website, employees, founded, cloud tier. Figures, not a feed of events. | | **CPPO Activity** | Private-offer activity. | | **Co-Sell** | Shared opportunities — the three most recent co-sells with the partner. | | **Tasks** | Open action items. | **Content (CMS)** blocks pull from your library: **Rich Text**, **Table**, and **Media Gallery**. A built-in card can only be added once — it greys out and reads "added" in the palette after that. Content blocks can be added as many times as you like, each pointing at a different library item. ### Working with blocks Hover a block for its toolbar — a row of unlabelled icon buttons. Hover each one for its tooltip: - **Drag to reorder** (the grip). You can also drag the block itself. Blocks reflow sideways within a row and vertically across rows. - **Make full width** / **Make standard width** (the rectangle) toggles the block between standard width and spanning the whole row. Only present on a 2- or 4-column canvas. - **Hide from partners** / **Show to partners** (the eye) keeps the block in the template but drops it from what partners see. - **Remove** (the bin) takes it out entirely. On a content block, a dropdown in its header picks which library item fills it, and **Manage** takes you to **Partner Views** in Settings to edit the library. :::warning **Manage leaves the editor without saving.** It behaves exactly like **Discard** — same exit, no publish, no confirmation prompt — so any blocks you've added, moved, resized, or hidden since your last **Publish** are lost. If you need to adjust the library mid-edit, click **Publish** first, then **Manage**. ::: **Preview** swaps the editor for the partner's view of the page — banner, section nav, and sidebar included — with hidden blocks dropped. Then click **Publish**. Publishing a template updates it for every partner already linked to it. ![The template editor — the Components palette on the left with its Built-in cards group (already-placed cards marked "added") above Content (CMS), the canvas of stacked blocks rendered with sample data and each showing its drag, width, hide and remove controls on hover, and the Columns 1 / 2 / 4 control beside Preview, Discard and Publish in the header](images/48-template-editor.png) ## Step 3 — Apply the Template to Partners Templates are assigned **per partner**. There are two ways in: **From Settings.** On the template's card, click **Apply to partners**, select partners from the picker, and confirm. Partners who already have this template are greyed out as "Already applied". Applying replaces whatever template each selected partner had. On the **Default Template**, "Already applied" covers more than you might expect: every partner with no explicit assignment already resolves to the Default, so the picker greys those out too. Only partners you've explicitly moved onto another template remain selectable there. **From the partner record.** Open the partner, click **Preview as {partner}**, then use **Apply a prebuilt template**. Picking one previews it in place — "this is what {partner} will see" — with **Cancel** and **Apply**. **Exit preview** returns to the inbound view. See [Work a Partner Record](/prm/work-a-partner-record/). :::warning **There is no tier-based assignment.** Tiers drive plenty elsewhere in Partner Management — event sharing, journey outcomes, commission plans — but not Overview templates. A template reaches a partner because you assigned it to that partner, or because it is your organization's default. Nothing else. ::: ## How Fours Decides Which Template a Partner Sees ```d2 direction: right partner: "Partner opens\ntheir portal Overview" { shape: rectangle } assigned: "Does this partner have\na template assigned?" { shape: diamond } isdefault: "Is one template marked\nDefault for your org?" { shape: diamond } anytemplate: "Are there any templates\nat all?" { shape: diamond } useassigned: "Render their assigned template" { shape: rectangle } usedefault: "Render the Default Template" { shape: rectangle } usefirst: "Render the first template in the library" { shape: rectangle } standard: "Render the standard Overview" { shape: rectangle style.stroke-dash: 3 } partner -> assigned assigned -> useassigned: "yes" assigned -> isdefault: "no" isdefault -> usedefault: "yes" isdefault -> anytemplate: "no" anytemplate -> usefirst: "yes" anytemplate -> standard: "no — nothing configured" ``` An assignment pointing at a deleted template behaves as no assignment, so that partner falls through to the default rather than seeing a blank page. ## Managing Templates Over Time - **Editing a template changes it for everyone linked to it.** If you only want to change one partner, clone the template first and apply the clone. - **The Default Template can't be deleted or renamed.** It's the fallback the resolution order depends on. - **A template in use can't be deleted.** Reassign its partners first — the template card lists them by name. - **The partner list on each template card counts partners who land on it by default too**, not just explicit assignments, so it reflects real reach. ## What This Doesn't Cover Partner Views controls the **Overview** page inside the portal. The portal's look and its front door are configured elsewhere: - [Brand Settings](/prm/brand-settings/) — logo, brand colors, and tagline. - [Partner Portal Login Page](/prm/partner-portal-login-page/) — the branded sign-in URL. - [Add Portal Users](/prm/add-portal-users/) — who can get into the portal in the first place. A handful of Overview elements are fixed and can't be added, removed, or reordered as blocks: the active-journey strip at the top of the page, and the Slack and Cloud Account IDs panels in the sidebar. --- Source: https://doc.fours.com/prm/connect-slack-for-partners/ # Connect Slack for Your Partners Connect your Slack workspace and map a channel to each partner, so Fours knows where to post co-sell activity, internal notes, and broadcasts. --- ## Overview Most partner conversations already happen in Slack. Connecting Slack to Fours lets you keep them there: each partner gets a Slack channel, and Fours posts to that channel instead of asking your team to copy updates across by hand. This page is the prerequisite for [Broadcasts](/prm/broadcasts/). A partner with no mapped channel is silently excluded from every broadcast audience — including **All partners** — so if a partner tells you they never received an announcement, check their channel mapping here first. :::info Changing these settings needs an Admin or Editor role. The standard **Viewer** role has no Partner Management permissions; a [custom role](/get-started/account/#custom-role-with-granular-permissions) with only `partners.read` still sees the controls, but the save is rejected. See [Account](/get-started/account/). ::: :::warning This page is for the selling organization. **Partner-side organizations** see a **Contact Sales** panel here instead of the configuration below — Slack channel setup is something the seller does for the partnership, not something the partner configures. ::: ## Connect Your Workspace 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Slack**. 3. If no workspace is connected — including after someone disconnects Slack under **Settings → Integrations** — the page reads **Slack not connected.** with a **Connect Slack in Settings → Integrations** link. Follow it to authorize the Suger app in your Slack workspace, then come back here. Once connected, the page header shows the connected workspace name. ![Settings → Partner → Slack — the connected workspace, the internal notifications channel with its Change button, and the partner channel table](images/43-slack-settings.png) ## Set the Internal Notifications Channel The **internal notifications channel** is your own team's channel. Internal notes posted on co-sells are mirrored here — **never to a partner channel** — so your team can discuss a deal without the partner seeing it. 1. Find the internal channel card near the top of the page. 2. Click **Change**. 3. Search for a channel by name, or paste a Slack channel ID directly (for example `C0123ABCD`) if the channel doesn't appear in search. 4. Confirm your choice. ## Map a Channel to Each Partner Below the internal channel card is a table of your partners and their Slack channels. 1. Use **Search partners by name…** to find a partner, or tick the connected-only filter to see just the partners that already have a channel. 2. On the partner's row, assign or edit its channel. The channel picker works the same way as the internal channel picker — search by name, or paste a channel ID. 3. To disconnect a partner, remove its channel mapping from the same dialog. The table paginates with **Previous** / **Next** and shows the page you're on. **Search runs on the server and matches the partner name**, so it covers your whole partner program — not only the rows currently loaded. The connected-only filter and the pagination then apply to whatever the search returned. :::info The table loads at most **2,000 partners at a time**, and that limit applies to the partners **matching your search**. With more than 2,000 matches it shows *"Showing the first 2,000 matching partners…"* — type more of the partner's name to bring it into range. An empty search box on a program larger than 2,000 partners shows only the first 2,000, which is why search, not paging, is how you reach the rest. ::: ![The partner channel table — a search box and connected-only filter above rows showing the three channel states: Connected, Add bot to channel, and No channel](images/43-slack-settings.png) ### Channel Status Each row carries one of three statuses: | Status | What it means | What to do | |--------|---------------|------------| | **Connected** | Fours can post to the channel. | Nothing. | | **Add bot to channel** | The channel is mapped, but the Suger bot is not a member of it, so posts will not land. | Invite the Suger app to that channel in Slack. | | **No channel** | No channel is mapped to this partner. | Assign one, or accept that this partner is excluded from broadcasts. | :::tip **Add bot to channel** is the status worth watching. The mapping looks correct in Fours, and nothing errors — the messages simply never appear in Slack. Inviting the app to the channel fixes it. ::: ## What a Mapped Channel Unlocks ```d2 direction: right slack: "Your Slack workspace\n(connected once)" { shape: rectangle } internal: "Internal notifications channel" { shape: rectangle } check: "Partner has a\nmapped channel?" { shape: diamond } channel: "Partner's Slack channel" { shape: rectangle } excluded: "Excluded — receives nothing" { shape: rectangle; style.stroke-dash: 3 } uses: "Broadcasts\nCo-sell activity" { shape: rectangle } notes: "Internal notes on co-sells" { shape: rectangle } slack -> check: "for each partner" check -> channel: "yes" check -> excluded: "no" uses -> channel: "posted to" notes -> internal: "mirrored to your team only" ``` - **[Broadcasts](/prm/broadcasts/)** — one message sent to every mapped partner channel at once. - **Co-sell activity** — posted to the partner's channel as it happens. - **Internal notes on co-sells** — mirrored to your internal notifications channel only, never to the partner's. ## Co-Sell and Commission Alerts in Your Team's Channels You can also send co-sell and commission lifecycle alerts to your **own team's** Slack channels, alongside the emails you already get. These alerts aren't set up on this page. They are notification scopes on your Slack integration: 1. Go to **Settings → Integrations** and open **Slack**. 2. Under **Notification Scope Configs**, click **Add notification scope**. 3. Choose the channels, then the scopes to send to them. See [Slack](/integrations/slack/#configure-notification) for how notification scopes work. | Scope | The card announces | | --- | --- | | `CREATE.SUGERCOSELL` | A new co-sell, registered by your team or shared with you. | | `REGISTER_ON_BEHALF.SUGERCOSELL` | A co-sell registered on a partner's behalf. | | `ACCEPT.SUGERCOSELL`, `DECLINE.SUGERCOSELL` | The other side accepted or declined a co-sell. | | `CLOSE_WON_REMINDER.SUGERCOSELL` | A co-sell marked Closed Won. | | `CLOSE_LOST.SUGERCOSELL` | A co-sell marked Closed Lost. | | `COMMISSION_TERMS_UPDATED.SUGERCOSELL` | New commission terms on a co-sell. | | `DEAL_UPDATED.SUGERCOSELL` | A change to a deal field the partner can see. Posts only while **Partners — Deal update emails** is switched on under **Settings → Notification**. | | `PENDING.COMMISSION`, `APPROVE.COMMISSION` | A commission pending, or approved. | | `PAYMENT_SENT.COMMISSION`, `PAYMENT_CONFIRMED.COMMISSION`, `PAYMENT_REJECTED.COMMISSION` | A commission payment sent, confirmed, or rejected. | | `CLAWBACK.COMMISSION` | A commission reversed. | | `UPDATE_PROPOSED.COMMISSION`, `UPDATE_APPROVED.COMMISSION`, `UPDATE_REJECTED.COMMISSION` | A proposed change to commission terms, and its approval or rejection. | How the cards behave: - **A link, never an action.** A card can carry an **Open in Fours** link to the deal or commission, but never a one-click action. Anyone in a channel could click one, so an alert that comes with a one-click link, such as a partner's link to approve new commission terms, is sent by email only. - **Deal values stay where they're shared.** A deal value appears only on the new co-sell, on-behalf registration, Closed Won, and Closed Lost cards, and only when it's shared on that deal. Commission cards show the commission amount, even on a deal whose value is hidden from the partner. ## Scope and Limits - **Slack only.** There is no Microsoft Teams equivalent for partner channels today. - **One channel per partner.** Fours posts to the partner's mapped channel, not to individual partner contacts. - **The bot must be in the channel.** Mapping a channel is not enough on its own — see the status table above. - **Seller-side only.** Partner-side organizations see a Contact Sales panel here instead of the configuration. - **The table loads at most 2,000 partners at a time.** The cap applies *after* the search filter, so searching by partner name reaches partners beyond it. Searching by channel name is not supported — search matches the partner name. --- Source: https://doc.fours.com/prm/partner-events/ # Create and Share Partner Events Run webinars, training sessions, and field events for your partner network, share them with the right partners, and see who's coming. --- ## Overview **Events** is where you publish anything your partners should show up to — a quarterly roadmap webinar, a certification session, a regional field event, or a plain calendar entry. You create the event, choose who it goes to, and partners RSVP from their own portal. :::info Creating and sharing events needs an Admin or Editor role. The standard **Viewer** role has no Partner Management permissions; a [custom role](/get-started/account/#custom-role-with-granular-permissions) with only `partners.read` still sees the **Create Event** button, but the save is rejected. See [Account](/get-started/account/). ::: ## Find Events Go to **Fours Console**, then **Partners**. In the sidebar, under **Workspace**, click **Events**. The feed splits into three tabs so you can tell your own events from your partners': | Tab | What it shows | |-----|---------------| | **All** | Every event you can see, yours and your partners'. | | **Shared** | Events your organization created and shared out. | | **Received** | Events a partner shared with you. | Switch between a **List** and a **Calendar** view with the toggle — both show the same filtered set, so the tab you're on still applies. ![The Events page on the All tab in List view — the All / Shared / Received tabs, the type filter and List/Calendar toggle, and four events showing their type badges, schedule, audience and RSVP counts](images/34-events-list.png) ## Create an Event Click **Create Event**. 1. **Title** — what partners will see, for example "Q3 Partner Roadmap Webinar". 2. **Type** — one of four: - **Webinar / Online Session** - **Certification / Training Session** - **In-Person / Field Event** - **General Calendar Event** 3. **Description** — what the event is about. 4. **Date**, then **Start** and **End** times, and a **Timezone**. 5. **Meeting URL** or **Address** — the field changes to match: online events ask for a link, in-person events ask for a location. 6. **RSVP** — whether partners can respond. 7. **Capacity** — optional, and **only available when RSVP is enabled**. Leave it blank for unlimited. 8. **Share with** — see below. :::warning An event goes live as soon as you save it. There is no draft state and no separate publish step — if it isn't ready for partners to see, don't save it yet. ::: ![The Create Event dialog — Title, Type, Description, Date with Start, End and Timezone, Meeting URL, an optional Capacity beside the RSVP toggle, and the Share with selector](images/35-create-event.png) ### Choose Who Sees It **Share with** offers three options: | Option | Who receives it | |--------|-----------------| | **All partners** | Everyone in your partner network. | | **Specific partners** | Only the partners you pick. You must select at least one. | | **Partners by tier** | Every partner in the tiers you pick. You must select at least one. See [Partner Tiers](/prm/partner-tiers/). | An event can't be saved until it has a title, a date, and a valid audience. ## Track RSVPs On an event you own, the **RSVPs** column shows the attending count — `12 / 50 attending` when you set a capacity, or just `12 attending` when you didn't. Once the event has passed, it reads `12 attended`, or *Event passed* if nobody RSVP'd as attending — but it is still the count of people who said they'd come, not a check-in count. To open the roster, choose **View RSVPs** from the row's **⋯** menu. Partners answer **Attending** or **Decline**. Only *Attending* responses count toward capacity — if someone declines after accepting, their seat is released. :::info The roster is a guest list, not a response log: it lists **only the people attending**, with their name and organization. Partners who declined, or who never answered, do not appear — so the row count in the roster always matches the attending count, and there is no way to see who said no. ::: If you set a **Capacity**: - A partner whose RSVP would push the event past capacity is refused. - You can't later lower capacity below the number already attending — Fours blocks it with *"Capacity can't be below the number of people already attending."* Raise the capacity instead, or wait for someone to decline. ![An owned event in the Events list with its RSVP count linked, and the roster dialog open over it — titled "RSVPs — Q3 Partner Roadmap Webinar", with the attending-out-of-capacity summary above a Name and Org table of the people attending](images/47-event-rsvp-roster.png) ## Removing an Event The only way to take an event down is to **delete** it. :::warning Deleting is permanent — the confirmation reads *"This can't be undone."* There is no cancel-but-keep-the-record option, so an event you delete disappears from your feed and from every partner's. If you need a record of a cancelled event, note it elsewhere first. ::: ## What Your Partners See Partners get a **receive-only** view of Events: - They see only the events shared with them — the **All / Shared / Received** tab row is hidden, because there is nothing to split. - There is no **Create Event** button; partners cannot publish events to you. - They respond with **Attending** or **Decline** from their portal. :::tip Because partners only ever see events shared with them, **Partners by tier** is the cleanest way to run a tiered program — a Gold-only enablement session never appears to anyone else. ::: ## Scope and Limits - **No draft or cancelled state.** An event is live from the moment you save it, and delete is the only way to remove it. - **RSVP is a simple yes/no.** There are no waitlists. - **Events are not calendar invitations.** Fours does not send an `.ics` file or write to a partner's calendar — the event lives in the portal. - A partner record also carries its own **Events** section; see [Work a Partner Record](/prm/work-a-partner-record/). --- Source: https://doc.fours.com/prm/connect-an-external-lms/ # Connect an External LMS Keep your courses where they already live, and let partners reach them from Fours without a second login. --- ## Overview If your partner training already lives in a learning management system (LMS), such as Skilljar or another platform that supports SAML, you do not have to rebuild it in Fours. Connect the LMS once and Fours can: - publish **external courses** that are a link into your LMS; - sign partners in on arrival, through SAML single sign-on, so there is no second password; - record who opened each course, and when; - with Skilljar, read completions back, so a finished course completes in Fours on its own ([Completion sync](#completion-sync)). Fours is the **identity provider** in this arrangement and your LMS is the service provider. Your LMS remains the authority on course content and completion. Here's what happens when a partner opens an external course, once everything below is in place: ```d2 shape: sequence_diagram partner: Partner suger: Fours lms: Your LMS partner -> suger: "Click Open in … on a course" suger -> suger: "Record the open" suger -> partner: "Send the browser to the course's destination link" { style.stroke-dash: 4 } partner -> lms: "Arrive at the course page" signin: "If your LMS asks who this is" { lms -> suger: "Ask who this is (SAML)" suger -> lms: "Email, FirstName, LastName" { style.stroke-dash: 4 } } lms -> partner: "Signed in, on the course page" { style.stroke-dash: 4 } ``` Because the partner is already signed in to Fours, the SAML exchange is usually invisible — the course simply opens. Setup is guided, and it starts with a conversation. To get started, contact your Fours representative. Self-service setup isn't available yet. | Fours | You | | --- | --- | | Issues the sign-in URL, metadata URL, identity provider entity ID, and signing certificate | Configure your LMS with them ([Step 2](#step-2-configure-your-lms)) | | — | Record both sides under **Partners → Settings → Training / LMS** ([Step 3](#step-3-record-the-values-in-fours)) | | — | Turn single sign-on on when you're ready ([Step 4](#step-4-turn-on-single-sign-on)) | | — | On Skilljar, optionally turn on [completion sync](#completion-sync) so finished courses come back to Fours | ## Before You Start Check these before you pick a date: - **Your LMS plan includes SAML single sign-on**, and you — or someone on your team — can reach its SSO settings. Some vendors offer SSO only on certain plans, or switch it on through their support team. - **Your LMS recognizes returning learners by email address.** Fours sends each learner's email address as the SAML Name ID. If your LMS matches learners on anything else, an existing learner can end up with a second account and lose their history. - **Your partner users have accepted their Fours invitations.** Single sign-on can only sign in people who have a Fours account. :::warning Single sign-on is switched on in your LMS, not in Fours. Check with whoever owns your LMS how enabling it affects the people who sign in there today, agree the timing, and rehearse on a test site first if your vendor offers one. ::: ## Configure the connection Four steps connect the two systems. Fours handles the identity side; you configure your LMS and record both sides in Fours. ### Step 1: Request the connection Contact your Fours representative and tell them which LMS you use. Fours sends you four values: | Value | What your LMS may call it | | ----- | ------------------------- | | **Sign-in URL** | IdP SSO URL, or SSO login URL | | **Metadata URL** | IdP metadata, or metadata XML | | **Identity provider entity ID** | IdP entity ID, or Issuer | | **Signing certificate** | IdP certificate, or X.509 certificate | ### Step 2: Configure your LMS 1. Open your LMS's SAML single sign-on settings and create a configuration. 2. **Import the metadata rather than pasting the certificate by hand** — from the metadata URL or its XML file, if your LMS offers that. The **Metadata URL** field in Fours gives the same advice. 3. **Map the attributes to these exact names:** | Attribute | What Fours sends | | --------- | ---------------- | | `Email` | The learner's email address. It is also the SAML Name ID. | | `FirstName` | The learner's first name in Fours. | | `LastName` | The learner's last name in Fours. | All three are required. Company and job title are not sent. :::warning After the first sign-in, check that all three attributes came through under these exact names, not just the email. ::: 4. **Set the Name ID format to email address.** This is how your LMS recognizes a returning learner. 5. Save the configuration, then send these values from your LMS to your Fours representative: - Service provider entity ID - Assertion consumer service (ACS) URL - Single logout (SLO) URL ### Step 3: Record the values in Fours 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Training / LMS**. 3. Under **LMS**, choose **Skilljar** or **Other (SAML)**. Single sign-on works with either; [completion sync](#completion-sync) needs Skilljar. Optionally, enter a **Display name**, such as the name of your partner academy — this settings page uses it to label its sections. The name partners see on a course's button comes from that course's own **LMS** field — see [Publish an external course](#publish-an-external-course). 4. Under **Give these to *{your LMS}***, enter the **Sign-in URL**, **Metadata URL**, and **Identity provider entity ID** Fours sent you. Copy the entity ID exactly as the metadata shows it. **Test connection** flags a mismatch, which your LMS would otherwise reject without saying why. 5. Under **Get these from *{your LMS}***, enter the **Service provider entity ID**, **Assertion consumer service (ACS) URL**, and **Single logout (SLO) URL** from Step 2. Fours keeps them as a record of what was exchanged, so a broken connection can be diagnosed later. 6. Click **Save** at the bottom of the page. 7. Click **Test connection**. It reads the values you saved, so save first. **Test connection** fetches the metadata from your metadata URL, which must be an `https://` address. The result reads **Metadata looks correct** or **Needs attention**, with each check listed separately: | Check | What it confirms | | ----- | ---------------- | | **Reachable** | The metadata URL answered. | | **Valid SAML metadata** | What it returned is SAML metadata. | | **Issuer matches what is saved here** | The entity ID in the metadata is the one you saved. | | **Email NameID offered** | The email-address Name ID format is available, so returning learners can be matched on email. | | **Signing certificate published** | The metadata carries a signing certificate. | The test checks the metadata only — it does not sign anyone in. If the test finds a signing certificate, **Download certificate** saves it as a `.pem` file, for an LMS that asks for the certificate on its own; until then the button stays disabled. The tab's **What we send about each user** section lists the same three attributes as Step 2. ### Step 4: Turn on single sign-on Do this last, once both sides are configured. 1. In **Training / LMS**, switch **External LMS single sign-on** on, then click **Save**. 2. Enable the SSO configuration in your LMS. The switch turns the connection on in Fours. It doesn't change where a course opens: **Open in …** always sends partners to the course's destination link. [Completion sync](#completion-sync) has a switch of its own, so turning single sign-on off doesn't stop completions coming back. ## Completion sync **Completion sync reads completions back out of your LMS, so an external course finishes in Fours on its own.** When your LMS reports that a partner finished a course, their enrollment becomes **Completed**, a journey's **Complete course** step waiting on that course ticks, and a journey that finishes this way can promote the partner's tier if it carries a tier outcome. It works with **Skilljar**. With **Other (SAML)** selected, single sign-on and open tracking work as before, but completions can't be read. Completions come back two ways: | Path | How fast | What it's for | | --- | --- | --- | | **Completion webhook** | Seconds | Skilljar sends each completion to Fours as it happens. This is the main path. | | **Scheduled check** | Slow | Fours asks your LMS about a few learners at a time, on a schedule, so it can take several days to come back round to everyone. It's the safety net that catches what the webhook missed. | ```d2 direction: right finish: "A partner finishes\na course in Skilljar" { shape: rectangle } webhook: "Completion webhook\nin seconds" { shape: rectangle } poll: "Scheduled check\na few learners at a time" { shape: rectangle } match: "Course, learner and\nenrollment all match?" { shape: diamond } skipped: "Passed over:\nunmatched course, unknown\nlearner, or not enrolled" { shape: rectangle; style.stroke-dash: 3 } completed: "Enrollment reads Completed" { shape: rectangle } journey: "Complete course step ticks" { shape: rectangle } tier: "A journey with a tier outcome\ncan promote the partner" { shape: rectangle } finish -> webhook finish -> poll webhook -> match poll -> match match -> completed: "yes" match -> skipped: "no" completed -> journey journey -> tier ``` ### Set up completion sync 1. In **Training / LMS**, set **LMS** to **Skilljar**. 2. Switch **Completion sync** on and enter your **Training domain**, for example `courses.example.com`. Fours never guesses it: your LMS's API is scoped to one training domain while one key reaches every domain in the account, so this is what keeps the sync pointed at the right site. Click **Save** at the bottom of the page. 3. Paste an **API key** from your LMS and click the **Save** button next to the field. Create it as a **read-only** key — in Skilljar, tick **Read Only** when you generate it. Fours only ever reads from your LMS, so a full-access key would grant delete rights nothing here uses. 4. Click **Sync now** to test the setup. It runs the same check the schedule does, straight away, and reports what it did — *"Applied 3 completions."* or *"Sync ran. No new completions to apply."* — plus how many it passed over as unmatched course, unknown learner, or not enrolled. A key your LMS rejects fails here, with your LMS's own message, instead of failing quietly later. 5. [Set up the completion webhook](#set-up-the-completion-webhook). 6. Link each external course to the matching course in your LMS. See [Publish an external course](#publish-an-external-course). The key is stored encrypted and never shown again; the field shows a **Stored** badge instead. To remove it, empty the field and click **Clear**, which switches completion sync off at the source. If completion sync is on but something it needs is missing — Skilljar isn't selected, or no training domain is saved — a warning under the switch says which. The section also shows when Fours last checked, or **Not checked yet**. ### Set up the completion webhook The webhook is the half Fours can't configure for you: creating it is a change in your LMS, and the key you gave Fours is read-only. Under **Completion webhook**: 1. Click **Generate secret** and copy the secret straight away. It's shown once and can't be retrieved; if you lose it, generate another and update your LMS. 2. In Skilljar, create a webhook with the **Target URL** shown on the page. Add a custom header whose name is the **Custom header name** shown on the page, with the secret as its value. Skilljar doesn't sign its webhook deliveries, so this header is what proves a delivery is genuinely yours. 3. Set the event type to `COURSE_COMPLETION`, or leave it empty to send every event — Fours ignores the ones it doesn't need. Once a secret exists, the badge next to **Completion webhook** reads **Secret generated** instead of **Not set up**, and the button reads **Generate a new secret**. Generating a new secret immediately stops deliveries that still carry the old one, until you update Skilljar. :::warning **If the secret in Skilljar stops matching, Skilljar turns the webhook off permanently, without telling anyone.** Completions still arrive through the scheduled check, just slowly. If completions that used to land in seconds start taking days, check the webhook in Skilljar. ::: ### How completions are matched A completion counts only when Fours can match all three of these. Anything it can't match is counted and passed over, never treated as an error: | Fours needs | Otherwise passed over as | What to do | | --- | --- | --- | | The course is linked to its course in your LMS | Unmatched course | Pick it under **Course in your LMS**. An unlinked course reports zero completions, however many partners finish it. | | The learner's email address belongs to a Fours user | Unknown learner | Make sure the learner has a Fours account under the same email address — the same people single sign-on can sign in. | | That user is enrolled in the course in Fours | Not enrolled | The learner enrolls in the course in Fours, or is assigned it. | A partner doesn't have to open the course from Fours first. Someone who went straight to your LMS is still recorded as having finished, as long as they're enrolled in Fours. **Re-running is safe.** A completion is recorded once. Running **Sync now** again, or getting the same completion from both the webhook and the scheduled check, changes nothing and never ticks a journey step twice. ## Publish an external course **Link external LMS** is a third kind of course, alongside the built-in editor and SCORM uploads. See [Build a Training Course](/prm/build-a-training-course/). An external course is only a destination, so it asks for less: | Field | Notes | | ----- | ----- | | **Course name** | What partners see, for example *Acme Partner Onboarding*. | | **Destination link** | Where the learner lands in your LMS. It must be a full `https://` address. | | **Course in your LMS** | Appears once [completion sync](#completion-sync) is set up, listing the courses published on your training domain. Pick the one this course mirrors so its completions can come back. Optional: without it the course still works, but no completion can be matched to it. | | **LMS** | The name on the partner's **Open in …** button, for example *Skilljar*. Left blank, the button reads **Open in external LMS**. | | **Category** | Where it sits in your catalogue. | | **Est. minutes** | Shown to partners as the expected time. | To link a course you've already created, open it in the course builder. **Course in your LMS** carries a **Not linked** badge until you pick one, and changing the link applies to the next published version. The destination is pinned to a version, so editing the course later does not silently repoint partners who are already working through it. You don't need a single sign-on connection to publish an external course. Without one, **Open in …** sends partners straight to the destination link, and your LMS signs them in however it normally does. ## What partners see On an external course the partner gets a single button — **Open in** followed by the course's LMS name — at every stage. There is no Start / Resume / Review progression, because Fours is not running the lessons and has nothing to resume. ## Verify Before Announcing It Before you tell partners, run these checks with a real partner user: 1. The partner clicks **Open in …** on a course in Fours and lands on that course page in your LMS, already signed in. 2. **An existing learner signs in and still sees their completion history**, with no new learner record. If not, stop and recheck the Name ID setting in [Step 2](#step-2-configure-your-lms). 3. A partner on a different device, with no existing session, can sign in. 4. In Fours, the course's **Enrollments** view shows that learner's last-opened date and open count. 5. If you use completion sync, finish a linked course as that partner, then check that their enrollment reads **Completed** in the course's **Enrollments** view. ## What you can still monitor **An external course reports that it was opened and, with completion sync, that it was finished — never how far through it a partner is.** Fours keeps a per-enrollment open ledger, so [Share and Monitor Training](/prm/share-monitor-training/) shows an **Opened** status and a count of how many partners have opened it — never a percentage complete. Tell your team these limits before go-live: - **Nothing in between comes back.** An external enrollment is **Not Started**, **Opened**, or — once your LMS reports a completion through completion sync — **Completed**. It never reads **In Progress**. In a course's **Enrollments** view, each learner shows **Last opened** with a date and an open count instead of a progress bar. - **"Opened" means "clicked the link."** The open is recorded when the partner clicks **Open in …**, before they reach your LMS — so it includes people who never got past your LMS's sign-in page. - **Certificates can't be earned from an external course**, even with completion sync on. You can attach one, but Fours issues a certificate only for a passed quiz or a completed SCORM package, and an external course has neither. - **Without completion sync, journey steps and tier conditions on an external course have to be completed by hand.** With it, a **Complete course** step ticks itself once the completion comes back. - **Signing out of your LMS doesn't end the Fours session.** That is a real limit, not a gap to work around: the lessons run in your LMS, so your LMS is the only place that knows how far a learner has got. Completion sync brings back the one fact it reports — that they finished. ## Troubleshooting | What you see | Usual cause | | ------------ | ----------- | | Sign-in fails with a signature error | Your LMS may hold an outdated or mistyped signing certificate. Re-import the metadata rather than pasting the certificate by hand ([Step 2](#step-2-configure-your-lms)). | | Learners sign in, but without a name | Check that your LMS maps the attributes under the exact names `Email`, `FirstName`, and `LastName` ([Step 2](#step-2-configure-your-lms)). | | Existing learners get brand-new records | The Name ID isn't set to email address, or your LMS matches learners on something else. Stop and check before more learners sign in. | | **Test connection** passes, but sign-in fails | The test checks the metadata only and never signs anyone in. Recheck the ACS URL and service provider entity ID exchanged in Steps 2 and 3. | | **Test connection** reports that no metadata URL is configured yet | The metadata URL wasn't saved. Enter it, click **Save**, then test again. | | A course reports zero completions, although partners have finished it | It isn't linked under **Course in your LMS** ([Publish an external course](#publish-an-external-course)). | | **Sync now** reports completions it passed over | Each count names the match that failed. See [How completions are matched](#how-completions-are-matched). | | Completions that used to land in seconds now take days | The webhook has stopped delivering, most often because the secret in Skilljar no longer matches. See [Set up the completion webhook](#set-up-the-completion-webhook). | ### The partner arrives signed out Check that **External LMS single sign-on** is switched on and saved in Fours ([Step 4](#step-4-turn-on-single-sign-on)), and that the SSO configuration is enabled in your LMS. **Open in …** always sends partners to the course's destination link; whether that page asks a visitor to sign in is decided by your LMS's own settings. ## Related - [Build a Training Course](/prm/build-a-training-course/) - [Share and Monitor Partner Training Courses](/prm/share-monitor-training/) - [Take a Training Course](/prm/take-training-course/) --- Source: https://doc.fours.com/prm/public-deal-registration-link/ # Take Deal Registrations Through a Public Link Give partners one public link where they can register a deal with you, with no Fours account and no sign-in. Share it directly or embed it on your own site, choose who may submit, and review every registration in Partner Co-Sells. --- ## Overview The **deal registration link** is a public page, branded with your company, where anyone who has the link can register a deal with you. You decide who may use it: - **Any company** — your partners, and companies that aren't partners yet. A company Fours doesn't recognize can still register a deal, and you review the company and the deal together. - **Connected partners only** — only companies already connected to you as partners. Anyone else is asked to apply to your partner program first. Every registration that goes through arrives in **Partners → Partner Co-Sells** as an **Inbound** co-sell. What else Fours sets up depends on who submitted it — see [What Happens to a Submission](#what-happens-to-a-submission). :::info This page covers your side of the link. For what a partner sees and fills in, see [Register a Deal Through a Public Link](/prm/submit-a-deal-registration-partner/#register-a-deal-through-a-public-link). ::: ## Before You Start - **Partner co-sell must be enabled for your organization.** The **Co-Sell** section under **Partners → Settings** only appears when it is. - **Set your portal slug first.** The link is built from it, and until one is saved the card asks you to set up your partner portal URL. The slug is set under **Partners → Settings → Login Page**. See [Choose your portal slug](/prm/partner-portal-login-page/#choose-your-portal-slug). - **You need an Admin or Editor role** to change these settings. See [Account](/get-started/account/). ## Turn On the Link 1. Go to **Fours Console**, then **Partners**. 2. Click **Settings** at the bottom of the rail, then **Co-Sell**. 3. On the **Deal registration link** card at the top of the tab, switch the toggle on. The rest of the card appears. 4. Under **Who can submit**, choose **Any company** or **Connected partners only**. See [Choose Who Can Submit](#choose-who-can-submit). 5. Optionally, list the sites that may embed the form under **Allowed embed domains**. See [Embed the Form on Your Site](#embed-the-form-on-your-site). 6. Click **Save**. Fours confirms with *"Deal registration link settings saved."* One **Save** covers the whole card. It saves only this card's settings, so it never changes anything else on the Co-Sell tab, such as auto-accept. ## Share Your Link With the toggle on, **Your link** shows the address partners use: ``` https://www.suger.io/deal-registration/{your-portal-slug} ``` The link is on `www.suger.io`, Fours' former address, which keeps serving this form so the links and embeds you've already shared keep working. - **Copy link** copies it, ready for an email or your partner page. - **Copy embed code** copies a ready-to-paste snippet for your website. - **Preview** opens the live form in a new tab. You can't edit the link here. It's built from your organization's portal slug, the same one your partner portal and branded login page use. Changing the slug changes all of those links at once, and every link you've already shared stops working, which is why Fours asks you to confirm a slug change before saving it. ### Embed the Form on Your Site The embed code places the form in an ` ![The Knowledge Base app — the knowledge base list on the left, and a detail view with the Files, Websites, and Connectors tabs (Files shown, with an indexed document and its per-row Deprecate and Delete actions)](images/09-insulin-knowledge-base.png) ## Opening the Knowledge Base App Knowledge Base is a built-in Insulin app. Open it from the **Knowledge Base** tile pinned to the desktop dock, or navigate directly to its window. Like other workspace apps, it opens as a resizable window with the knowledge base list on the left and a detail panel on the right. ## Creating a Knowledge Base 1. Click the **+** button in the Knowledge Bases list (or **Create one** on the empty state) 2. Configure the following: | Field | Description | |-------|-------------| | **Name** | A descriptive name for the knowledge base | | **Description** | Optional summary of what it contains | | **Visibility** | **User** (only visible to you) or **Organization** (shareable with your team). Creating an organization knowledge base requires org admin access. | | **Embedding model** | The model used to index and search documents. The options depend on who owns the knowledge base — see [Choosing an embedding model](#choosing-an-embedding-model) below. | | **Search mode** | **Hybrid** (recommended), **Vector only**, or **Keyword only** | 3. Click **Create** ### Choosing an embedding model Every document is embedded with the knowledge base's embedding model, and searches use that same model. Which models you can pick depends on who owns the knowledge base: Two kinds of model can appear in the picker, and each has its own condition. **Fours-hosted models** — **BGE-M3** or **Qwen3 Embedding 0.6B** — need no key of your own, and **BGE-M3** is the default when you don't pick one. They are offered to either visibility, but only while your organization allows Fours' platform key (**Settings → Organization → AI Model Policy → Allow Fours platform key**, described in [Getting Started](/insulin/getting-started/#ai-model-policy)). Turn that switch off and the hosted models leave the picker for everyone in the organization. **Your own providers' models** are added for each provider that scope has connected: **OpenAI** (text-embedding-3-small and -large), **Gemini** (Gemini embedding 2), **OpenRouter** (BGE-M3), **DeepInfra** (BGE-M3, Qwen3 Embedding 0.6B), **Fireworks** (Nomic Embed v1.5), and **Together** (multilingual-e5-large-instruct). - **Organization knowledge bases** add the providers the **organization** has connected. - **User (personal) knowledge bases** add the providers **you** have personally connected, never the organization's. :::warning **A bring-your-own-key organization with no embedding provider connected cannot create a knowledge base.** With Fours' platform key switched off, the hosted models are not selectable, and a hosted model chosen anyway is refused with *"…runs on Fours' hosted key, which this organization has disabled."* A model from a provider that scope has not connected is refused the same way. Connect an embedding provider — or leave the platform key on — before you need one. ::: :::info **Gemini embedding 001 has been retired** in favour of **Gemini embedding 2**. A knowledge base already indexed with the old model keeps working and can still be searched and re-indexed; it is simply no longer offered for a new selection, and shows as *legacy* where it appears. ::: Each option is labelled with its provider, vector size, and hosting — for example `openai · 1536 dims · BYOK` or `deepinfra · 1024 dims · Suger-hosted`. ![The New Knowledge Base dialog with the owner-scoped Embedding model chooser — an Organization knowledge base showing a model labelled google · 1536 dims · BYOK](images/kb-create-embedding-model.png) :::info You can change the embedding model later from **Settings** — see [Changing the embedding model](#changing-the-embedding-model). Because changing it re-indexes every document, it's best to pick the model you expect to use up front. ::: ## Adding Content Open a knowledge base to reach its detail panel, which has three tabs: **Files**, **Websites**, and **Connectors**. ### Files Upload documents directly or paste text. - **Upload file** — Select files, or drag and drop them onto the panel. Supported formats: PDF, DOCX, and text formats including `.txt`, `.md`, `.csv`, `.tsv`, `.log`, `.json`, `.html`, `.xml`, and `.yaml`. Maximum **25 MB** per file. - **Paste text** — Paste raw content and give it a name. Maximum **2 MB** of text. Uploading a file with the same name replaces the existing document in place. The file list shows each document's **Name, Pages, Chunks, Size,** and **Status**. #### Previewing a document **Double-click a file row** to open it in the [Preview](/insulin/getting-started/) app. There is no button for this — the row itself is the control, and hovering it says *"Double-click to open a preview."* Preview is offered for **uploaded and pasted files only**. Website and connector documents have no single original file behind them, so their rows do not open. Two things a preview can answer with instead of the document: | Response | When | What to do | |---|---|---| | **Document is too large to preview** | The stored file is over **25 MB** | Nothing — the document is still indexed and searchable; only the preview is refused | | **Too many document reads in flight; please retry** | More than **4** document reads are already in flight | Your request waits for a slot and is only refused if none frees up within about **10 seconds**; retry after that | ### Websites Add a public URL to crawl its pages into the knowledge base. 1. Enter a URL (for example, `https://docs.example.com`) 2. Set the **Depth** — how many link levels to follow (1–10, default 3). Depth 1 is the start page only; depth 3 follows links three levels deep. 3. Click **Add** The crawler imports up to 100 pages of main content as documents. Websites re-crawl only when you trigger a **Re-sync** manually — they do not sync automatically. The list shows **URL, Docs, Depth, Last Sync,** and **Status**, with per-row sync and remove actions. While a site is indexing, its row shows a progress bar and a percentage (see [Watching indexing progress](#watching-indexing-progress)). #### Adding many websites at once Adding sites one at a time doesn't scale past a handful. Click **Bulk add** on the Websites tab to open the **Bulk add websites** dialog, which reads a spreadsheet of URLs and creates one website per row. 1. Click **Bulk add** 2. Click **Choose file** and pick an `.xlsx`, `.xls`, or `.csv` file. The sheet needs a `url` column; `depth` is optional and defaults to 3. A header row is not required — a bare column of links works, and header names are matched loosely (for example, *Website URL* and *Max Depth* are both understood). 3. Review the preview. Every row is listed with its **URL** and **Depth**, and a summary line above the table counts what was found — for example *42 rows · 39 to add · 2 invalid · 1 duplicate*. Rows that can't be imported are flagged in place with the reason why (see the table below). 4. Click **Add _N_ websites** to import. Only the valid, non-duplicate rows are sent — nothing is written until you confirm this counted list. A progress bar runs while the import works through the rows one at a time, and the result reads **Added _N_**, or **Added _N_ · _M_ failed** when some rows didn't take, so a partial import is never silent. Reasons a row is skipped: | Reason shown on the row | What it means | |-------------------------|---------------| | **Missing URL** | The row has no URL in it. | | **Not a valid URL** | The value isn't a URL. | | **Must be an http or https URL** | Only `http://` and `https://` addresses can be crawled. | | **Must be a public address — internal and private hosts can't be crawled** | The host is internal or private. | | **Depth must be a whole number from 1 to 10** | The depth value is outside the allowed range. | | **Already added** | The knowledge base already has that URL, or the sheet lists it twice. | Two more things to know: - The cap is **500 rows per import**. A larger file is **refused, not truncated** — the dialog reports how many rows it found and asks you to split the file and run it again, rather than quietly importing the first 500 and dropping the rest. - **Imported websites are added but not crawled.** Start a sync when you're ready. ### Connectors Connectors keep a knowledge base in sync with issues, tasks, and files from your connected integrations. You can add **one connector per integration** per knowledge base. | Connector | What it syncs | What you configure | |-----------|---------------|--------------------| | **GitHub** | Issues and pull requests as Markdown (no source code) | Repositories; toggle **Issues** and **Pull requests**; optional max items per repo | | **ClickUp** | Tasks and Doc pages | Spaces; toggle **Tasks** and **Docs**; optional max tasks per list | | **Google Drive** | Documents and files (Google-native docs exported to text) | Folders (synced recursively) and individual files, via search-as-you-type | *Notion is not yet available as of July 2026 (no target date committed).* To add a connector: 1. Open the **Connectors** tab and pick a provider card 2. If the underlying integration is not connected yet, the card shows **Set up the integration first** — connect it in **Settings**, then return 3. Click **Connect**, select the scope (repositories, spaces, or folders/files) 4. Choose whether to **Auto-sync** the connector 5. Click **Connect** to start the first sync A connected card shows a scope summary (for example, "3 repos"), an indexed count (`Indexed items: X/Y`), and the last sync time — plus, while it is indexing, a progress bar with a percentage (see [Watching indexing progress](#watching-indexing-progress)). You can **Re-sync**, **Stop sync**, **Edit scope**, or **Remove** the connector. :::info Organization knowledge bases support only the **Google Drive** connector. GitHub and ClickUp connectors are available on user knowledge bases. ::: ## Syncing and Indexing **Manual sync** — Trigger a sync, stop an in-progress sync, or re-index a single document at any time from the tab actions. **Automatic sync** — Only connectors with **Auto-sync** enabled are kept current automatically. Insulin sweeps due connectors about once an hour: it runs a full reconcile when the last full sync was more than 24 hours ago, and an incremental sync when the last sync was more than an hour ago. Websites and individual files do not auto-sync. As documents are added, Insulin splits each one into chunks, generates embeddings, and stores them for search. Only documents that finish indexing become searchable. Each document and connector shows a status: | Status | Meaning | |--------|---------| | **Pending** | Queued, not yet processed | | **Indexing** | Being parsed and embedded (a progress bar shows percent complete) | | **Indexed** | Successfully indexed and searchable | | **Failed** | Indexing or sync failed — hover the alert icon for the error | | **Deprecated** | Retired from search but not deleted — chunks are preserved and it can be restored | | **Deleted** | Removed from the knowledge base | Lists refresh automatically while anything is pending, indexing, or syncing. ### Watching indexing progress A status word alone doesn't tell you whether a large crawl is nearly done or has barely started, so **websites** and **connectors** report their own progress while they index. Under the source's name you get a progress bar with a **percentage**, alongside the running count of documents indexed out of the total discovered — `12/48` on a website row, or `Indexed issues: 12/48` on a connector card. The bar appears only while the source is actually **Indexing**. Once it finishes, the counters stay as a final tally and the bar goes away — a bar parked at 100% would read as still-working. The counts are read from the documents themselves each time the list loads, so the number you see is what has genuinely finished indexing at that moment, not an estimate or a cached tally. A knowledge base also reports its own **Re-indexing** progress — distinct from the per-document statuses above — while it rebuilds embeddings after an [embedding-model change](#changing-the-embedding-model). It counts the documents already searchable on the new model, `3 of 42 documents searchable`, and calls out separately any that **failed**, because those need a re-index rather than more waiting. Search keeps working throughout, answering from the documents already rebuilt. The spinner stops when nothing is moving any more, even if the knowledge base is not fully searchable — documents that only **failed** are reported as a warning with an **Index them now** button rather than as work in progress, because waiting will not clear them. ### Retiring a document You can retire an indexed **file** without deleting it. Use **Deprecate** on an indexed file to drop it from search results while keeping its document and chunks intact, then **Restore** it later to bring it back into search — no re-upload needed. Deprecate and Restore apply to files only; website and connector documents cannot be deprecated. Deprecate is offered only once a file has finished indexing. **A sync will not bring a deprecated document back.** If a synced source still contains a document you deprecated, the next sync skips it rather than re-indexing it — deprecating is a decision, and a sweep that quietly undid it every hour would make the control useless. **Restore** is the only way back into search. One thing to expect on the way back: **restoring re-indexes the file**. It returns as **Pending** and is searchable again once that finishes — usually about as long as indexing it took the first time, and needing nothing from you. The reason is that a retired file is skipped by an [embedding-model change](#changing-the-embedding-model), so its stored embeddings may have been built with a model the knowledge base has since moved off, and putting those straight back into search would return poor matches rather than an error. ## Testing Search Use **Test search** in the detail panel to preview what an agent would retrieve before attaching the knowledge base. Enter a query, set the number of results (Top K, up to **20** here), pick a search mode, and adjust the vector weight. Results show the matching content, its source document, and a relevance score. The Test-search cap of 20 applies only to this preview. The knowledge base's persisted **default Top K** is set in Settings and can be as high as **50**, and an agent searching at query time can request up to **100** results. ## Settings Open the **Settings** (gear) panel from a knowledge base's detail view to adjust how it is described, chunked, and searched. | Setting | What it controls | |---------|------------------| | **Name** | The knowledge base's display name | | **Description** | Optional summary of its contents | | **Chunk strategy** | **Fixed size** or **Semantic** — how new documents are split before indexing | | **Search mode** | **Hybrid** (vector + keyword), **Vector only**, or **Keyword only** | | **Top K results** | The persisted default number of results (1–50) | | **Vector weight** | For hybrid search, how much to favor vector vs. keyword matches (0–1) | | **Embedding model** | The knowledge base's **Current model**, with a **Change model** control to switch to another eligible model (re-indexes every document — see [Changing the embedding model](#changing-the-embedding-model)) | :::info Changing the **chunk strategy** applies to **new syncs only**. Existing documents are not re-indexed, so a mix of chunk strategies can coexist until you re-index or re-sync a document. ::: ### Changing the embedding model The **Embedding model** section of Settings shows the knowledge base's **Current model**. To switch it, choose another model under **Change to** and click **Change model**. The list offers only models *other* than the current one, scoped to the knowledge base's owner (see [Choosing an embedding model](#choosing-an-embedding-model)); if no other eligible model is available, the panel says so. ![The Embedding model section of Settings — the Current model, a Change to picker of other eligible models, and the Change model button that starts a re-index](images/kb-change-embedding-model.png) A knowledge base always has a model from the moment you create it — Insulin picks a Fours-hosted one when you don't choose, and asks you to choose when your organization only allows its own providers. If you ever see a knowledge base with **no model set** (an older one, created before models were recorded), it can neither index nor be searched until you pick one here; documents wait as **Pending** and searches say so rather than returning nothing. Choosing a model starts indexing them. Because switching is a heavy operation, Insulin asks you to confirm: > **Change embedding model?** Switching to *<model>* re-embeds all *<N>* documents in this knowledge base, which takes provider time and spend. Until a document has been re-embedded it will not appear in search results; the ones already done keep working throughout. Once you confirm: - The knowledge base **re-embeds its documents** onto the new model, one at a time, and the section shows how many are ready — `3 of 42 documents searchable`. A document that can't be processed is marked **Failed** and the rest continue; re-index it from the Documents tab once you have fixed the cause, or use **Index them now** in the progress panel to retry every outstanding document at once. - **Search keeps working.** It answers from the documents already on the new model and hides the rest, so results are never mixed across two models. An agent searching mid-rebuild is told how much of the knowledge base it actually covered, so a thin answer is never mistaken for an empty knowledge base. - You **can change the model again** at any point, including mid-rebuild — the new choice supersedes the one in progress and re-queues the documents. - The switch is complete when every document reports ready. **Retired (deprecated) documents are skipped**; each is re-indexed if you restore it later. - If progress stops before every document is ready — a worker restart, an interrupted rebuild — **Restart indexing** in the same panel picks up exactly what is outstanding. It never re-embeds a document that already finished, so it is safe to use at any time. :::info Either visibility can **select** a Fours-hosted embedding model whenever your organization allows Fours' platform key — it needs no key of your own, and it is the default when you don't choose one. What differs is the automatic recovery: an **organization** knowledge base whose selected BYOK provider isn't available when it first indexes falls back to a Fours-hosted model on its own and notes it in Settings (*"Fell back to a Fours-hosted model."*). A **user** knowledge base does not switch models behind your back — if the provider you picked stops working, the affected documents are marked **Failed** and you choose a different model yourself. ::: The **Danger Zone** at the bottom of Settings holds **Delete Knowledge Base**, which removes the knowledge base and all of its documents, chunks, and embeddings. This cannot be undone. ## Connecting a Knowledge Base to an Agent Agents retrieve context by searching the knowledge bases available to them: - **Custom agents** search the knowledge bases explicitly attached to them. In the agent's create or edit form, the **Knowledge Bases** section lists eligible knowledge bases as checkboxes — select one or more. A user-level agent can attach your user-level knowledge bases; an org-level agent can attach organization knowledge bases. - The built-in **Insulin** assistant searches your own knowledge bases automatically. You can also pick an explicit set — see [Choosing which knowledge bases Insulin uses](#choosing-which-knowledge-bases-insulin-uses) below. At query time an agent can search up to three knowledge bases and cites the source document for each result. See [Agents](/insulin/agents/) for how to create and configure custom agents. ### Choosing which knowledge bases Insulin uses Open **Chat**, select the **Insulin** agent, and click the pencil button in the conversation header (labelled *Insulin model settings*). Its **Knowledge Bases** section controls what Insulin can search. By default the section shows an **Automatic** badge and Insulin searches every knowledge base you own, read-only. Ticking or unticking any row switches to an explicit selection, which then takes over completely: | Selection | What Insulin searches | |-----------|-----------------------| | **Automatic** (default) | Every knowledge base you own, read-only | | One or more ticked | Exactly the ticked knowledge bases | | Nothing ticked | No knowledge base at all | The list covers every knowledge base you can reach — the ones you own, plus organization knowledge bases shared with you, each marked with a **Shared** badge. Grounding Insulin in an organization knowledge base no longer requires a custom agent. Each ticked row also carries an access mode, **Read** or **Edit**, with the same meaning as for a custom agent (see [Agents](/insulin/agents/)). Choosing **Edit** only expresses intent: Fours re-checks your own role on that knowledge base immediately before every write, so picking **Edit** on one you can only read grants you nothing, and access revoked mid-conversation stops the next write. Select **Reset to automatic** to discard the selection and go back to the default. :::info This selection is personal to you and applies only to the built-in Insulin assistant. Custom agents keep their own attachments, and [Inbox](/insulin/inbox/) has a separate, read-only selection it uses when drafting email replies. ::: ![The agent panel's Knowledge Bases section — the Automatic badge, the note that Insulin searches all your knowledge bases by default, and a per-knowledge-base checkbox with its Read/Edit access selector](images/19-agent-knowledge-bases.png) ## Sharing and Roles Knowledge bases follow Insulin's role-based access control. **Your org role does not, by itself, grant access to any organization knowledge base.** Access to an org knowledge base comes only from a **per-knowledge-base share** (added as Admin, Editor, or User) or from **org-wide sharing** (as Editor or User). Even an organization admin cannot open an org knowledge base they were not shared on. Org admin access is required only to *create* an organization knowledge base — not to open existing ones. **Knowledge base role** — Each knowledge base grants members one of four roles: | Role | Search & read | Add / sync content | Delete & manage sharing | Transfer ownership | |------|:---:|:---:|:---:|:---:| | **Owner** | Yes | Yes | Yes | Yes | | **Admin** | Yes | Yes | Yes | No | | **Editor** | Yes | Yes | No | No | | **User** | Yes | No | No | No | - **User** knowledge bases are private to their creator — even organization admins cannot access them unless the knowledge base is shared with them. - **Organization** knowledge bases start visible only to their creator (the owner). They become reachable to others only through a per-KB share or org-wide sharing, as described above. - Ownership of an organization knowledge base can be transferred by its owner to another active member of the organization. When you open the **Settings** of a knowledge base shared with you, they show an owner-and-role banner, and a member below **Editor** (a **User**) sees them **read-only** — including the **Change embedding model** control, which is disabled. See [Working with a Shared Resource](/insulin/getting-started/#working-with-a-shared-resource). See [Getting Started](/insulin/getting-started/) for the overall Insulin roles and permissions model. ## Limits | Limit | Value | |-------|-------| | File upload size | 25 MB per file | | Pasted text size | 2 MB | | Website crawl depth | 1–10 (default 3) | | Website pages per crawl | Up to 100 | | Website rows per bulk import | 500 (a larger file is refused) | | Connectors per knowledge base | One per integration type | | Test-search results | Up to 20 | | Persisted default Top K (Settings) | Up to 50 | | Agent search results per query | Up to 100 | | Knowledge bases searched per agent turn | Up to 3 | | Knowledge bases selectable for Insulin | Up to 500 | | Knowledge bases attached to Inbox drafting | Up to 100 | | Knowledge bases searched per Inbox draft | Up to 3 | | Results per knowledge base per Inbox draft | Up to 4 | ## Use Cases - **Product support** — Crawl your public docs site and let a support agent answer with grounded, cited responses. - **Engineering context** — Connect GitHub repositories so a code or triage agent can reference open issues and pull request discussions. - **Project knowledge** — Sync ClickUp spaces so a project agent can answer from current tasks and Docs. - **Team drive** — Connect a Google Drive folder of playbooks, contracts, or reports so agents work from the same source of truth your team uses. --- Source: https://doc.fours.com/insulin/channels/ # Channels Channels are group conversations where multiple users and agents collaborate in a shared thread. --- ## What Are Channels? A channel is a persistent group chat within Insulin. Unlike a standard conversation, which is between you and one agent, a channel brings together multiple team members and multiple agents into a single thread. Everyone in the channel sees the same messages, can ask questions, and can interact with agents that have been added. Channels are useful when a task requires input from several people or benefits from multiple specialized agents working together. Inside a channel you get the same **Messages**, **Files**, and **Jobs** tabs as a one-on-one conversation. Its **Jobs** tab lists the [jobs](/insulin/jobs/) belonging to the agents that are members of the channel, and only the ones you are allowed to see. In an organization channel, work that Planner schedules belongs to the channel itself, and every member sees it in the conversation — see [What Planner can and cannot do](#what-planner-can-and-cannot-do). Sending messages requires the **USER** role or higher — **VIEWER** members can read but not send. ![A channel — a shared thread marked with an org badge, the members icon (top-right) for managing Agents and People, an @mention that addresses specific agents, and the tab bar above the composer](images/07-insulin-channel.png) ## Creating a Channel 1. Click the **+** button next to **Channels** in the sidebar 2. Enter a channel name and optional description 3. Choose the ownership type: - **Personal (only you)** — The channel is private to you. Only your own user-level agents can be added. - **Organization (shareable)** — The channel belongs to the organization and can be shared with team members. **Only org-level agents** can be added as members. 4. Under **Agents**, search for an agent by name or description and pick it from the list, then give it a short role label describing its function 5. On an organization channel, also add teammates under **People** — search by name or email and choose each person's access role (ADMIN, EDITOR, USER, or VIEWER) 6. Click **Create** Changing the ownership type clears any agents and people you already picked, because the two types draw from different sets. :::warning Creating an **Organization** channel requires organization administrator access. Non-admins cannot select this ownership type. Org-level channels can only include org-level agents as members — if you need a user-level agent, create a personal channel instead. ::: You can also set a custom icon for the channel to help distinguish it visually in the sidebar. Ownership cannot be changed after a channel is created. ## Channel Roles Every user in a channel has one of these access roles: | Role | Permissions | |------|-------------| | **OWNER** | Full control — manage members, edit channel settings, delete the channel, and transfer ownership (org-level channels only) | | **ADMIN** | Manage members and edit channel settings | | **EDITOR** | Send messages and interact with agents | | **USER** | Send messages and interact with agents | | **VIEWER** | Read messages only — cannot send messages or trigger agent actions | The user who creates a channel is automatically the **OWNER**. On org-level channels, ownership can be transferred to another organization administrator (see [Editing and Deleting Channels](#editing-and-deleting-channels)). Organization admins do not automatically become channel admins. Org-level channel access comes from explicit membership or org-wide sharing, so private collaboration spaces stay private until the channel owner or admin shares them. ## Channel Knowledge Bases A channel can connect to **as many [knowledge bases](./4.knowledge-base.md) as it needs** (up to 20) to ground its agents on shared context — the same way agents do. Select them in the channel Settings panel; the picker is searchable, and each connected knowledge base gets its own access mode: | Mode | What it means | |------|---------------| | **Read** | The channel planner can search and retrieve from that knowledge base. | | **Edit** | The planner can search it and also create, update, and deprecate files in it. | The mode is per knowledge base, so a channel can read from a reference library while editing its own working notes. Member agents are always **read-only** against every channel knowledge base, regardless of mode — only the planner can write, and only where Edit is selected. ![The agent panel's Knowledge Bases section — the Automatic badge, the note that Insulin searches all your knowledge bases by default, and a per-knowledge-base checkbox with its Read/Edit access selector](images/19-agent-knowledge-bases.png) ## Adding Members Channel members can be **users** or **agents**. Both are managed from a single **Members** panel (open it with the members icon in the channel header), which has an **Agents** section and a **People** section. :::info Editing the Agents section requires **EDITOR** or higher role. Adding people or changing sharing requires **ADMIN** or higher. ::: **To add a user** (org-level channels only): 1. Open the channel 2. Click the members icon in the channel header 3. In the **People** section, add a user from your organization 4. Assign an access role (ADMIN, EDITOR, USER, or VIEWER) Only org-level channels can have user members. Personal channels are limited to you and your agents. **To add an agent:** 1. Open the channel 2. Click the members icon 3. In the **Agents** section, add an agent 4. Assign a role label that describes the agent's function (e.g., "researcher", "analyst") On an organization channel, which organization agents you can add depends on your role on the **agent**, not only on the channel. An agent shared with the whole organization can be added by anyone who can use it; any other organization agent can be added only by its owner or someone who holds **ADMIN** on it. The same rule applies to the agents you pick while creating a channel — a create that includes one you may not add is refused. The Members panel lists every organization agent either way, so adding one you may not add fails with *Failed to add agent.* Each channel holds up to **20 agent members** and up to **20 user members**. If a channel is at its cap, remove an inactive member before adding another one. ## Joining, Previewing, and Leaving Channels An owner or admin can share an organization channel with the whole company using the **Share with entire organization** toggle in the Members panel. When enabled, they pick a default shared role of **Viewer**, **User**, or **Editor** (ADMIN is not offered for org-wide sharing). Shared channels become discoverable and appear in the sidebar for other members. You can: - **Preview** a shared channel to read its messages before joining (read-only) - **Join** a shared channel to start participating at its default shared role Your effective role is determined by the channel's shared role setting or the role explicitly assigned to you by the channel owner or admin. **Leaving a channel:** Any member except the owner can leave a channel they no longer need. The owner cannot leave — they must first transfer ownership to someone else. ## Searching Across Channels Click **Search…** at the top of the Chat sidebar to open the search dialog — *"Search agents, channels, and messages…"*. It searches all three at once and groups the results under **Agents**, **Channels**, and **Messages**. Use the arrow keys or your mouse to pick a result; selecting one takes you straight to it. Every agent and channel result is tagged so you can tell at a glance where it lives: | Tag | Meaning | |-----|---------| | **org** | Owned by your organization. | | **user** | Yours — a personal channel, or one of your own agents. | | **system** | Built in by Fours. Appears on agent results only. | A channel you have not joined but can discover is marked **Not in channel** next to its name, so search doubles as the way to find shared channels you aren't a member of yet. Type something with no matches and the dialog tells you plainly: *No results found for "…"*. ![The Chat window with the search dialog open — a query in the "Search agents, channels, and messages…" field and results grouped under Agents, Channels and Messages, each row tagged org or user, with a "Not in channel" marker on a channel the user has not joined](images/25-channel-search.png) ## How Agents Participate When you send a message in a channel, agents added as members can respond. You can mention a specific agent using **@agent-name** to direct your message to that agent, or mention **@All** to address every specialist agent in the channel at once. The mention autocomplete shows agents and users in the channel. Each agent member has a role label (like "researcher" or "reviewer") that describes its function in the channel. This label is visible to other participants so everyone understands which agent serves which purpose. How coordination works depends on the channel's ownership type: - **Personal channels** — The built-in **Insulin** agent acts as the coordinator. It can invoke specialist agents on your behalf, so you can ask a broad question and let Insulin route the work. Specialist agents in a personal channel can also hand off to each other. - **Organization channels** — The coordinator is **Planner**, an organization-owned agent that belongs to the channel rather than to any one member. Specialist agents respond directly to the @mentions they receive; a message that mentions nobody goes to Planner, which plans the work, assigns each part to the member agent best suited to it, and posts a combined summary once they have replied. Specialists never hand off to each other directly in an organization channel — **only Planner delegates**, and a specialist's attempt to pass work to another specialist simply doesn't happen. That rule is what keeps two agents from volleying a task back and forth in a room your teammates are reading. **A message addressed to nobody is always picked up.** Type into an organization channel without @mentioning anyone and Planner takes the turn and routes the work on from there. You never get silence back — if you're not sure which agent to ask for, just ask. Planner is available only in organization channels, and Insulin is not available there. That separation is deliberate: Insulin is your personal assistant and runs with *your* connected accounts, which should not be used to answer in a room your teammates read. ### What Planner can and cannot do | | | |---|---| | **Plans and delegates** | Breaks a request into pieces and assigns each to a member agent. | | **Reads the channel's knowledge bases** | At the mode the channel configured, and can write where Edit is selected. | | **Sets channel goals and schedules work** | Scheduled work belongs to the channel, so every member of that channel sees it in the conversation. | | **Has no integrations** | Planner cannot reach email, calendar, files, or any third-party system — permanently, by design. When a request needs one, it declines and names the member agent that can do it. | | **Uses no personal data** | Planner never reads your personal integrations, knowledge bases, or memory — its answers do not change depending on which member sent the message. | Because Planner draws on your organization's model configuration rather than any individual's, an organization channel answers even when the person writing has no model provider connected of their own. A message that @mentions only people (no agent) is treated as human conversation and no agent replies. :::info **@All** addresses every *specialist* agent in the channel — it does not trigger the channel's coordinator (Insulin in a personal channel, Planner in an organization channel). ::: ### Long-running work in a channel A channel agent can keep working across many turns to finish a multi-step request. Its progress arrives as ordinary messages in the channel, and anyone in the room steers or stops it by writing a normal message — "focus on the AWS ones", "stop". See [Long-running work](/insulin/agents/#long-running-work) for how this behaves. :::warning **The tool-approval card does not appear on channel turns.** Insulin can pause a solo web chat, or a conversation with it in Slack, and ask you to **Allow** or **Deny** a sensitive action before it runs — but a turn in an Insulin channel cannot render that card or send your decision back, so it never pauses to ask. See [Tool Approvals](/insulin/agents/#tool-approvals) for exactly where the gate is and isn't armed. ::: ## Editing and Deleting Channels Channel owners and admins can: - **Rename** the channel or update its description - **Change the icon** - **Remove members** (both users and agents) - **Transfer ownership** — available on org-level channels only. Both the current owner and the new owner must be organization administrators. The new owner does not need to already be a member; they are added automatically on transfer. - **Delete** the channel entirely (OWNER only) ## Use Cases - **Deal review** — Add a sales agent, a data analyst agent, and your sales team to review a deal together. - **Incident response** — Bring together operations, engineering, and an alert-monitoring agent to coordinate a response. - **Weekly reporting** — Set up a channel with a reporting agent and stakeholders who need visibility into weekly metrics. - **Cross-functional collaboration** — Combine agents with different specializations (CRM, marketplace data, revenue analysis) in one thread so the team gets multi-domain answers without switching contexts. --- Source: https://doc.fours.com/insulin/jobs/ # Jobs Jobs are automated agent runs — started on demand, on a recurring schedule, or when an event arrives. --- ## What Are Jobs? A job is one thing: a definition (which agent, and what to ask it) plus a **trigger** that decides when it runs. There is no second kind of object to learn — a job you start by hand and a job that fires on a schedule are the same record with a different trigger. The Jobs app opens as a searchable table of every job you can see. Each row carries an icon for its trigger kind; hover the icon for a tooltip naming it. | Trigger | Icon | Tooltip | How it works | |---------|------|---------|--------------| | **Manual** | Lightning bolt | *Manual* | Runs the agent once, when you start it. | | **Cron** | Calendar clock | *Cron* | Runs the agent on a recurring schedule defined by a cron expression. | | **Push** | Eye | *Push* | Listens for events. When one arrives, the job evaluates its filter and runs the agent if the event passes. | Open a job and the same information appears as a badge on its detail page reading **Manual**, **Cron**, or **Push**. Every trigger creates a **run** record you can inspect, so you always have visibility into what ran, when, and whether it succeeded. ### Reading a row Beside each job's name sit small tags saying what kind of job it is and whether it is switched on. The **Status** column carries the latest run's status as a chip of its own, so the column you scan for status is the one that has it. | Tag | Appears on | Means | |-----|-----------|-------| | **manual** / **cron** / **push** | Every row | The job's trigger kind | | **goal** | Goal jobs | The job runs a goal loop rather than a single turn (see below) | | **active** | Cron and push rows | The job is switched on and will fire | | **off** | Cron and push rows | The job is switched off and will not fire on its own | A manual job carries no **active**/**off** tag, because it has no switch to be in either state. ### Single-turn and goal jobs Beyond its trigger, a job runs in one of two modes: | Mode | What a run does | Leading icon | |------|-----------------|--------------| | **Single** | One agent turn — ask, answer, done. The default. | The trigger kind's own icon | | **Goal** | A goal loop pursued across rounds until the objective is met or you stop it | A target | A goal job is the [long-running work](/insulin/agents/#long-running-work) surface with a job record behind it, and its detail page links back to the conversation the rounds are written into. :::info **Goal jobs cannot be created over REST.** The mode is reported on a job you read back, but it is not a field you can send: `POST /jobs` and `PATCH /jobs/{id}` do not accept it. Ask the assistant for the goal you want and it sets the mode when it creates the job. ::: ![The Jobs app — the search box and Agent, App, Channel and Status filters above a job list, each row showing its trigger icon, agent, status, and last run](images/06-insulin-jobs.png) ### Finding a job The list header holds a **Search…** box plus four filters: | Filter | What it narrows to | |--------|--------------------| | **Agent** | Jobs that run under one agent. | | **App** | Jobs created from one Insulin app. Jobs created before app provenance was recorded, or created by an agent with no app context, group under **Unassigned**. | | **Channel** | Jobs whose agent belongs to one channel. | | **Status** | Jobs whose latest run is in one state. | Each filter opens with an "any" option (for example **Status: any**) that clears it. Filters apply server-side, so they hold as you scroll past the first page of results. Columns — **Agent**, **App**, **Channel**, **Status**, and **Last run** — can be dragged wider or narrower; **Name** absorbs the change. A filter for something the window already pins is not offered. Open the list from an agent and there is no Agent filter; open it from a channel and there is no Channel filter — the control would only let you contradict the context you opened. ### The Jobs tab in a chat or a channel Jobs also appear inside Chat. A solo agent chat and a [channel](/insulin/channels/) both show **Messages**, **Files**, and **Jobs** tabs. A channel's Jobs tab lists the jobs belonging to the agents that are members of that channel, resolved for you server-side — and only the ones you are allowed to see. This embedded view is a narrow panel, so it drops the search box and the four filters and shows just **Status** and **Last run** next to each name; the surrounding window already tells you which agent or channel you are looking at. Clicking a row here opens the job in the **details drawer** on the right — the same drawer a goal or job card in the conversation opens — rather than replacing the page, so the tab you were on stays where it was. ## How Jobs Are Created There is no "Create Job" form in the Jobs app — the list only lets you search, open, and manage existing jobs. You create a job in one of two ways: - **Ask the assistant in chat.** Tell the built-in Insulin agent what you want to automate (for example, "every weekday at 9am, summarize new AWS entitlements"). The agent creates the job for you, picking the trigger kind that matches what you asked for. See [Conversations](/insulin/agents/#conversations). - **Use the REST API.** `POST /jobs` creates a job programmatically. If you don't specify an agent when creating a job, it runs under the built-in **Insulin** agent. Otherwise it runs under the [agent](/insulin/agents/) you name, with that agent's access to resources and integrations. :::info A job you create runs within your scope, so the agent has access to the same resources and integrations you do. It is private to you: **only its owner** can see it, run it, edit it, or delete it. That includes organization administrators — being an org admin does not give you someone else's jobs. The exception is work Planner schedules in an organization channel: it belongs to the channel, and every member of the channel sees it — see [Channels](/insulin/channels/#what-planner-can-and-cannot-do). ::: ## Triggers Every job has exactly one of the three trigger kinds above. Manual jobs need nothing else. Cron jobs need a schedule; push jobs need an event source and, optionally, a filter. ### Push sources A push job subscribes to an event source: - **Fours events** are the marketplace events Insulin already knows about. When created over REST, the source must match `suger..` — for example `suger.OFFER.ACCEPT`. Sources that don't match this pattern are rejected. - **Third-party events** — GitHub (`github.`), Google Calendar (`calendar.`), and Gmail (`gmail.`) — require a live OAuth connection to that provider and can only be created by asking the assistant, which registers the subscription for you. A push job's detail page shows its **Source** and, if one is set, its **Filter**. :::info Fours event payloads are scrubbed of personal data (emails, secrets, tokens) before the agent sees them or a run record is stored. ::: ## Cron Scheduling Cron expressions define when a scheduled job runs. Standard cron syntax is supported: | Expression | Schedule | |------------|----------| | `0 9 * * 1-5` | Every weekday at 9:00 AM | | `0 */6 * * *` | Every 6 hours | | `0 0 1 * *` | First day of every month at midnight | | `*/30 * * * *` | Every 30 minutes | A cron job's detail page shows the raw expression in its header; hover it for a plain-English reading of the schedule. Alongside it are **Last triggered** and **Next** timestamps. **Next** appears only when there is a genuine upcoming run — a disabled or just-re-enabled job has a frozen schedule, so no misleading "next run" is shown. **The expression is the whole schedule.** There is no timezone field, no plain-interval field ("every 6 hours" is written as a cron expression, not chosen from a list), and no start or end date — a cron job has one cron expression and nothing else. Because no timezone is attached to it, `0 9 * * 1-5` means 09:00 on the service's clock rather than 09:00 wherever you happen to be reading the page; check the **Next** timestamp to see when a schedule actually lands for you. To stop a job on a given date, disable or delete it. ## Filter Expressions Filters let you control which events actually trigger an agent run. When an event arrives on a push job — or when a cron tick fires with a payload — the filter expression is evaluated against the event payload. If the filter returns false, the run is skipped and recorded with the **Filtered** status. Filters use [filtrex](https://github.com/m93a/filtrex) syntax — a safe, sandboxed expression language. The event payload is available under the `event` namespace. **Examples:** ``` event.source == "aws-marketplace" ``` ``` event.amount > 1000 ``` ``` event.action == "entitlement_created" and event.partner == "AWS" ``` ``` lower(event.status) == "active" ``` **Available functions:** `lower()`, `upper()`, `includes()` (checks if an array contains a value). **Dot notation** is supported for nested fields: `event.buyer.name`, `event.offer.info.commits`. :::tip If no filter expression is set, every event passes and triggers an agent run. ::: ## Runs Every job has **one detail page**, whatever its trigger kind, and every trigger creates a **run** record on it. The header carries the job's title, its trigger badge, and its state — a run-status badge on a manual job, or an **Active** / **Off** badge on a cron or push job. Below it sit the agent's name and the relevant timestamps. A **model badge** sits between the agent's name and the timestamps, but only on a **manual** job, and only when that job pins a model. A manual job that inherits its agent's default model shows no badge, and a cron or push job never shows one — so the absence of a badge is not the absence of a model. The page also shows the job's **instructions** — the text the agent is actually given. Every trigger kind now reads the job's prompt first and falls back to its description only when there is no prompt, so a cron or push job created over REST shows what it will run rather than repeating its own title. Under the header, a manual job shows the outcome of its latest run as a card: | Card | When it appears | What it holds | |------|-----------------|---------------| | **Result** | The latest run completed, **or was cancelled** and produced something | The agent's answer, rendered as Markdown. | | **Error** | The latest run failed | The error message the run ended with. | A cancelled run keeps its Result card because stopping a goal partway through is a normal way to end one, and the rounds it did complete are still worth reading. Every job then has a **Runs** table with three columns: | Column | What it shows | |--------|---------------| | **Started** | When the run began. | | **Status** | The run's outcome. | | **Duration** | How long the run took. | Select a run to open its detail panel, which has three tabs — and picks the right one for you: a **failed** run opens on **Steps**, where the reason usually is. | Tab | What it holds | | --- | ------------- | | **Output** | What the run produced. | | **Steps** | The tool-call transcript — which tools ran, in what order, each call's **Args** and its **Result** or **Error**, and how long each took against wall clock. | | **Input** | What the run received: for a push run, the event payload. | **Steps is persisted, not reconstructed.** A run that threw still keeps the transcript of everything it did before it failed, which is what makes a partial run diagnosable. The tab distinguishes its two empty cases rather than showing one blank panel: *This run recorded no steps.* means the run genuinely did no tool work, while *No transcript recorded* means the run predates transcripts or ended before it began work. The table pages in more runs as you scroll, and reads *None yet.* until the job has fired for the first time. Each run ends in one of these statuses: | Status | Meaning | |--------|---------| | **Pending** | The run is queued and waiting to start. | | **Running** | The agent is currently running. | | **Completed** | The agent finished successfully. | | **Failed** | The agent encountered an error. | | **Cancelled** | An in-flight run was stopped. | | **Filtered** | The event did not pass the filter expression and was skipped. | | **Rate limited** | The run was skipped because the job or organization hit its rate limit. On the Inbox mailbox watch for Gmail (**Inbox · Gmail**) it can also mean the run finished but Gmail rate-limited part of its work; those messages are tried again on a later delivery. | Filtered and rate-limited events still create a run row, so nothing that fired is invisible. ![A cron job's detail page — the Active and Cron badges beside the schedule, the agent and Last triggered / Next timestamps, and the Runs table with its Started, Status and Duration columns](images/16-job-detail-cron.png) ![A manual job's detail page — the title with its Completed and Manual badges, then the agent and the Created / Started / Done timestamps (this job pins no model, so no model badge sits between them), the prompt, the Result card rendered as markdown, and the Runs table below with one run expanded to show that run's own result](images/29-job-detail-manual.png) ### Rate limits To keep automations from overwhelming your workspace, **runs that Insulin starts for you** — a cron tick, or an arriving push event — are rate limited: | Limit | Value | |-------|-------| | Per job | 60 runs per hour | | Per organization | 300 runs per hour | Limits apply over a rolling one-hour window and are fixed — there is no setting for them. A run that exceeds one is recorded with the **Rate limited** status rather than executing. **Only one manual path skips the limit.** Running a *manual* job — the **Run** button, or the REST run endpoint — goes straight to execution. **Run now** on a cron or push job does not: it replays the job through the same path a real tick or event takes, so it is filtered and rate limited exactly like an automatic run, and can be recorded as **Rate limited**. What **Run now** does bypass is the enabled check, which is why it works on a switched-off job. Either way the job's in-flight rule still applies: one run at a time. The REST run endpoint accepts manual jobs only — call it on a cron or push job and it answers `400`, naming the trigger endpoint to use instead. ```d2 direction: down classes: { q: { shape: diamond; width: 250 } box: { width: 230; style.border-radius: 8 } rec: { width: 230; style.border-radius: 8; style.stroke-dash: 3 } } evt: "A push event arrives,\nor the cron schedule fires" { class: box } filt: "Filter expression\npasses?" { class: q } lim: "Under the per-job and\nper-org hourly limits?" { class: q } manual: "You run a manual job\n(Run, or the REST run endpoint)" { class: box } skipped: "Run recorded as\nFiltered" { class: rec } limited: "Run recorded as\nRate limited" { class: rec } go: "The agent runs" { class: box } evt -> filt filt -> skipped: "no" filt -> lim: "yes" lim -> limited: "no" lim -> go: "yes" manual -> go: "not rate limited" runnow: "You press Run now on\na cron or push job" { class: box } runnow -> filt: "replays the trigger" ``` ## Managing Jobs Open a job from the list to reach its detail page. The action buttons in the header are icons; hover one for its label. Which buttons appear depends on the trigger kind. **A manual job:** - **Run** — Start the job. Offered only while the job is pending; a job allows at most one in-flight run at a time, so if a run is already active a second Run is rejected with "Job already has an in-flight run." - **Terminate** — Stop a run that is currently going. While a run is in flight the header also shows a spinning **Running** indicator. - **Delete** — Permanently remove the job and its run history. You are asked to confirm by name. **A cron or push job:** - **Run now** — Fire the job immediately; a run is created as if its schedule or event had arrived. This works even while the job is switched off, so you can test a paused automation. (The REST trigger endpoint and the assistant also accept an optional payload to exercise the filter against sample data; the in-app **Run now** button fires with an empty payload.) - **Enable / Disable** — A switch that pauses the job without deleting it. A disabled job never fires on its schedule and shows an **Off** badge instead of **Active**. - **Delete** — Permanently remove the job and its run history. You are asked to confirm by name. :::info There is no edit form in the Jobs app. To change a job's name, schedule, filter, or assigned agent, ask the assistant (it uses an `update_job` action) or send a `PATCH` request to the REST API. ::: ## Use Cases - **Marketplace monitoring** — A cron job that checks for new entitlements or expiring offers daily and summarizes changes. - **Automated alerts** — A push job on Fours marketplace events that runs an agent to evaluate severity and notify your team. - **Recurring reports** — A cron job that runs a data analyst agent weekly to generate revenue or usage reports. - **Co-sell pipeline tracking** — A cron job that reviews partner referrals on a schedule and flags stale opportunities. --- Source: https://doc.fours.com/insulin/marketplace/ # Marketplace Marketplace is where you discover and install reusable Insulin capabilities — agents and skills — for yourself or, as an org admin, for your whole organization. --- ## What Is the Marketplace? Marketplace is a curated catalog of pre-built [agents](./3.agents.md) and skills for common workflows. Instead of building everything from scratch, you browse the catalog, review an item, and install it into your workspace. Installed items become part of your workspace: you can use installed agents in conversations, assign them to [jobs](./6.jobs.md), add them to [channels](./5.channels.md), and enable or edit installed skills for your team's needs. ## Stores: Personal and Organization Open **Marketplace** from the desktop dock. It opens as a window with a left sidebar. Depending on your role, the sidebar shows one or two **stores**, and each store has an **Agents** and a **Skills** entry: | Store | Who sees it | What installing does | |-------|-------------|----------------------| | **Personal** | Everyone | Creates a private copy in your own workspace. | | **Organization** | Org admins only | Creates an org-shared copy that is visible to your whole organization. | The Organization store is shown only to org administrators. Installs, imports, edits, and deletes at the Organization store affect everyone in your organization and require admin access. ![The Marketplace app — a left sidebar with the Personal store (and, for admins, an Organization store), each listing Agents and Skills; the Agents catalog shows each item's install state, Featured badge, and category tags](images/04-insulin-marketplace.png) ## Installing an Item 1. Open **Marketplace** 2. Pick the **Personal** or (as an admin) **Organization** store 3. Open **Agents** or **Skills** 4. For skills, stay on the **Skill Store** tab (where templates live) 5. Search or browse, then open a card to review its details 6. Click **Install** Installing is idempotent: re-installing the same item does not create a duplicate — it returns your existing copy, and installed cards show an **Installed** badge. ## Skills ### What Are Skills? A skill is a markdown-based instruction package containing procedures or domain knowledge. When an agent needs information a skill covers, it loads the skill's content into its context and follows the instructions within. Skills let you codify team knowledge — standard operating procedures, style guides, troubleshooting runbooks, product specs — and make it available to any agent during a conversation. ### How Agents Use Skills During a conversation, an agent loads relevant skills on demand. The agent reads the skill's content and incorporates it into its response. This means: - The agent follows procedures documented in the skill - The agent applies domain-specific rules and constraints from the skill - The agent references terminology and definitions from the skill You do not need to manually tell an agent to use a skill. Agents discover and load enabled skills automatically based on relevance to the current conversation — a skill's **Trigger** (described below) helps them decide when it applies. ### The Skills Page Each Skills page (Personal or Organization) has two inner tabs: | Tab | Contents | |-----|----------| | **Skill Store** | Fours-curated skill templates. **Install** lives here. Templates are authored by Fours admins under **Settings → Template**, so the store may be empty for some organizations. | | **My Skills** (Personal) / **Org Skills** (Organization) | The skills you own at this store. Each card has an **Enable/Disable** toggle, plus **Delete** and a click-through detail view. | Use the search box to filter either tab by name, description, category, and tags (the My/Org Skills tab also matches a skill's trigger). **Featured** templates carry a badge in the Skill Store — there is no separate Featured filter. ### Adding a Skill The **Add** dropdown (top-right of the Skills page) is where every skill comes in. **How many methods it offers depends on which store you are in — four in the Personal store, three in the Organization store:** | Method | Personal | Organization | What it does | |--------|:--------:|:------------:|--------------| | **Build with Agents** | Yes | — | Opens Chat seeded with a prompt so you can author a skill collaboratively via the `/skill-creator` command. | | **Upload a skill** | Yes | Yes | Drop a `.md`/`.markdown` file or a `.zip` package from your computer (see below). | | **Import from GitHub** | Yes | Yes | Paste a GitHub URL — a repo, folder, blob, or a raw `SKILL.md` URL. | | **Install from SkillsMP** | Yes | Yes | Search [skillsmp.com](https://skillsmp.com) and import a public skill from its underlying GitHub package. | **Build with Agents** is the only difference between the two stores. A skill you author in chat is always personal, so the Organization store does not show that option at all — its Add dropdown lists the other three. #### Uploading a skill 1. On the Skills page, click **Add → Upload a skill** 2. Drag and drop a file, or click to browse: - A single **markdown** file (`.md` or `.markdown`, up to 50 KB) - A **`.zip` package** (up to 10 MB) — the zip must include a `SKILL.md`; referenced files (references, scripts, assets) are preserved for runtime loading 3. For a markdown file, click **Generate** — Insulin normalizes it into a draft. Review and edit the prefilled fields (name, description, prompt, trigger, category, tags), then click **Save**. Name, description, and prompt are required. 4. For a `.zip` package, click **Import** — it imports directly, no review step The skill is now available to agents in your workspace. :::info A raw `raw.githubusercontent.com` `SKILL.md` URL imported from GitHub also goes through the review-and-save flow; repo, folder, and blob URLs import the full package directly, preserving referenced files. ::: ### The Trigger Field Every skill has a **Trigger** — a short description of when the skill applies. Agents use it to decide whether a skill is relevant to the current conversation. When you upload or import a markdown skill, the trigger defaults to the skill's description; you can edit it in the review form or later from the skill's detail view. ### Skill Format Skills are markdown-based packages. A simple skill can be a single markdown file; a packaged skill can include supporting files such as references, scripts, or assets. A well-structured skill includes: - A clear title describing the skill's purpose - Step-by-step instructions or reference material - Examples where helpful - Constraints or rules the agent should follow ```markdown # Creating AWS Private Offers ## Steps 1. Verify the buyer's AWS account ID 2. Confirm pricing terms with the sales team 3. Set the offer expiration date (default: 14 days) 4. Include a custom EULA if required by the buyer ## Rules - Never create offers with more than 30% discount without VP approval - Always include the standard support terms - Expiration date must be at least 7 days from creation ``` :::info Keep skills focused on a single topic. Multiple small skills work better than one large skill, because agents load only what is relevant to the current conversation. ::: ### Managing Skills Open a skill from the My Skills / Org Skills tab to reach its detail view. Skill cards show a **provenance badge** (From template, Uploaded, From GitHub, From SkillsMP, Built with Agents, or Custom) so you can tell where each skill came from. The detail view shows the same badges, except a SkillsMP-imported skill appears there as **Custom**. From here you can: - **Enable / Disable** — Toggle whether the skill is available to agents. A disabled skill stays in your library but is excluded from agent use — no need to delete it. - **Edit** — Update the skill's name, description, prompt, trigger, category, or tags - **Delete** — Remove the skill from your workspace (cannot be undone) ![A skill open from My Skills — the Enable toggle beside the skill name, the "From template" provenance badge under the description, then the Category & tags, Trigger and Prompt sections, with Edit and Delete in the footer](images/26-skill-detail.png) :::warning In the **Organization** store, creating, importing, editing, and deleting skills requires org admin access. Deleting an org skill permanently removes it **for everyone** in your organization. ::: ## What Gets Installed Installing a catalog item copies its payload into your workspace. Agents and skills carry different payloads: | Item | What is copied | |------|----------------| | **Agent** | System prompt, default model, welcome message, conversation starters, and icon. | | **Skill** | Prompt body, trigger, category, tags, and any auxiliary files (from a packaged skill). | Installed agents appear in your agent list; installed skills appear in your My Skills / Org Skills tab. You can customize them after installation — they are fully yours to edit. ## Managing Installed Items After installation, agents and skills from the marketplace behave identically to ones you create yourself. You can: - Edit an agent's system prompt or configuration, or a skill's fields - Assign agents to [jobs](./6.jobs.md) or [channels](./5.channels.md) - Enable, disable, or delete items you no longer need ## Discovering New Capabilities The marketplace catalog is updated as new agents and skills are added. Check back periodically, and use the search box to find items by name, category, or tags. Featured items are badged in the catalog. :::tip If you have a workflow that would benefit from a specialized agent or skill, start with the marketplace — there may already be one that fits your needs. ::: --- Source: https://doc.fours.com/insulin/custom-apps/ # Custom Apps Custom Apps are interactive tools you build with AI inside Insulin, using **AI Studio**. --- ## What Are Custom Apps? A Custom App is a reusable interface, dashboard, form, or workflow tool you build and edit in **AI Studio**, Insulin's app builder. Use a Custom App when a workflow needs more structure than a chat answer, such as a revenue dashboard, a deal review tool, a co-sell tracker, or an internal operations screen. AI Studio builds a real, browser-native app. When you approve a project, Studio mounts a self-contained npm project — its own `package.json`, framework configuration, and editable source — and runs it live in your browser, so the preview you see is the working app rather than a static mock. You publish a saved version to production to give the app its own URL. Custom Apps are different from built-in Insulin apps such as Chat, Jobs, Marketplace, Knowledge Base, Inbox, Settings, Files, Browser, or Git. Built-in apps are part of the Insulin workspace. Custom Apps are apps your team creates, runs, edits, and shares. ![The Custom Apps workspace — Org Apps and My Apps in the sidebar, "New App" to start the AI builder, and a live preview pane rendering a saved app](images/05-insulin-custom-apps.png) ## When to Use a Custom App Use a Custom App when you want to: - Turn a repeated marketplace workflow into a reusable interface - Build a dashboard or report from connected systems - Create a form-like tool for sales, operations, or partner workflows - Share an internal app with teammates without building a separate product For one-off questions, use [Chat](/insulin/agents/#conversations). For repeatable background work, use [Jobs](/insulin/jobs/). For packaged expertise, use [Agents](/insulin/agents/) and [Marketplace](/insulin/marketplace/). ## Build Dashboards with AI Custom Apps are the recommended way to build dashboards and reports in Insulin. As we continue to expand AI-powered analytics, the legacy Analytics experience is being deprecated. Your existing Analytics dashboards are not moved across automatically: they stay on the Analytics page, which keeps working until a removal date is announced, and none is committed yet. Instead of relying on fixed dashboards, users can create dashboards tailored to their own marketplace workflows using AI. You can create a dashboard by simply describing what you need in natural language. For example: - "Show my top customers by marketplace revenue over the last 90 days." - "List overdue marketplace payments." - "Build an AWS Marketplace revenue dashboard." - "Track offer acceptance rates and pending private offers." The AI builder generates an interactive dashboard that you can continue refining through conversation or by editing the generated app. ### Migration from Analytics If you currently use the legacy Analytics dashboards, we'll help you migrate them to AI Custom Apps. Our team can help recreate your existing dashboards as AI Apps while preserving the reports and workflows your team relies on. If you have any questions about migration or need assistance, please contact your Customer Success Manager. ## The Creation Interview Creating a new Custom App runs a three-step wizard — **Describe**, **Clarify** and **Plan** — before any code is generated. The pattern is **AI proposes → you decide → Studio builds**, and nothing is created until you approve the plan. | Step | What happens | |------|--------------| | **Describe** | Answer *What should this app help your team do?* in a few sentences — who will use it and what they need to get done, up to 4,000 characters — or start from an example: **Deal desk approvals**, **Partner referrals**, **Renewal follow-ups** or **Team requests**. On the same step, choose **App Ownership** (**Organization** or **Personal**) and the **AI model** that builds the app, or leave the model on Auto. | | **Clarify** | Under *Here's what I heard*, the AI restates your idea and who it is for. If it misread you, **Not quite right?** lets you say what to change, then **Update**. Choose *What kind of app?* — one option is marked **Recommended** — and answer the AI's questions; each offers a few choices plus **Something else…** for your own words. | | **Plan** | Under *Your plan*, set the **App name** and choose the **First release**: checked items go into the first release and the rest are saved for later. **Add your own** items, and keep at least one checked. Settle anything under **Still to decide**, review the **Questions for the builder** — they go into the brief unresolved — and pick a **Look & feel**. **See the exact brief** shows the text the builder starts from. | Click **Build my app** on the Plan step to create the app. Studio sets up the app's own npm project — its `package.json`, framework configuration, and editable source — and the builder starts from your plan. You can inspect and change every generated file afterward in AI Studio. ![Creating a new Custom App — describing the outcome in the AI product interview, with the step progress across Describe, Confirm, Scope, Access and Review](images/10-insulin-create-app.png) ```d2 direction: down classes: { box: { width: 260; style.border-radius: 8 } gate: { shape: diamond; width: 260 } } describe: "Describe\nWhat should the app do?\nOwnership and AI model" { class: box } clarify: "Clarify\nThe AI's reading and its questions" { class: box } plan: "Plan\nFirst release, open decisions,\nlook & feel" { class: box } approve: "Approve the plan" { class: gate } build: "Build\nStudio sets up the npm project\nand builds it in the browser" { class: box } publish: "Publish\nProduction URL + owner secrets" { class: box } run: "Run\nEmbedded in the runner window" { class: box } describe -> clarify -> plan -> approve approve -> build: "Build my app" build -> publish: "publish a saved version" publish -> run: "live URL" ``` Once the first build finishes, you keep working on the app in AI Studio — asking for changes in the assistant chat, editing the source, and saving new versions. ### Discuss before you change The builder's composer has a **Discuss** toggle beside the model picker — *Discuss changes without editing files*: - **Off** (default) — your message changes the app and produces a new live-preview build. Use this to make changes. - **On** — the builder answers in prose and can't edit the app's files. Use this to ask questions, plan an approach, or sanity-check an idea before you commit to a change. When a discussion reply proposes a concrete change, it shows an **Implement this** button. Clicking it turns Discuss off and sends the suggestion as your next edit — a one-click path from discussion to implementation. ### Mark an area of the preview Once a preview is rendered, a **Mark area** button appears on the assistant's composer. Turn it on, draw a circle around the part of the preview you mean, and your next message is scoped to just that area — for example, "make this chart taller" or "change this label." Press **Esc** to clear the selection. This is the precise way to refine a specific part of a generated app instead of describing the whole screen. ### Choose the AI model The builder includes a model picker (the sparkle button near the composer) so you can choose which model generates the app. You first choose it on the wizard's **Describe** step, or leave it on Auto, and can change it here later. Models are **grouped by provider**, and the grouping is driven by the server rather than a fixed list — connect another provider, such as [Cloudflare Workers AI](/integrations/cloudflare/) or [DigitalOcean GradientAI](/integrations/digitalocean/), and its group appears in the picker. The Fours-hosted models have a group of their own. Which models appear in the groups depends on the app's **ownership**: - **Organization apps** list **Your key** rows built from your organization's own connected provider keys (BYOK). Only providers you have connected contribute rows; connect a provider to add its models. - **Personal apps** list **Your key** rows for the providers *you* have connected — a personal app never reads your organization's keys. Connect a provider to add its models. Ownership decides only **whose** BYOK keys are listed. **Fours' key** (Fours-hosted) rows are offered to personal and organization apps alike, so you can build an app before connecting any provider of your own. An organization administrator can also constrain the picker, in two ways that behave differently: - **Turning the Fours-hosted fallback off** removes every **Fours' key** row for everyone in the organization, in both kinds of app. Only your own connected keys remain. - **Restricting which providers may be used** removes the **Fours' key** rows served by a provider that is not on the allow-list. Your own **Your key** rows are still listed — a model on a restricted provider is rejected when the app runs rather than being hidden from the picker. The model you pick is pinned on the app, so saved apps keep building with the same model. ## Multi-File Source A Custom App is a real npm project, not a single text blob. Every text file in it is editable — the app's own code under `src/app/`, and also `package.json`, configuration, and framework files — and supporting files can hold components, helpers, data-shaping code, and database migrations. Binary files are read-only. This lets AI Studio build more maintainable apps: - UI code can be split into focused files - The app's own `package.json` and lockfile decide which dependencies it uses - You can browse and edit every text file on the [Code surface](#studio-surfaces), and download the complete npm project An app's working tree is held on the server, which allows up to **2,000 files** per app. ## Studio surfaces AI Studio is a single window with an assistant panel on the left and a workspace on the right. The workspace switches between five surfaces. **Preview** and **Settings** are tabs of their own; **Code**, **Terminal** and **Data** share a **More** menu. | Surface | Where | What it shows | |---------|-------|---------------| | **Preview** | Tab | The running app, live, at desktop / tablet / phone widths. Open it full-screen over the tab, or [mark an area](#mark-an-area-of-the-preview) to scope a change. | | **Settings** | Tab | Everything about the app that is not its code, in sections: **General** (how it appears in Apps), **Access** (ownership, sharing, and [who can open it](#who-can-open-a-published-app)), **AI model**, **Secrets** (the owner's own [secrets](#publishing)), **Database** (the [published app's data](#data-an-app-keeps-for-itself)), **Analytics**, and **Danger zone**. | | **Code** | More menu | The project's file tree — filter, open and edit any text file (binary files are read-only), and **Download** the complete npm project. | | **Terminal** | More menu | A shell against the app's workspace, and a **Logs** view of the running app. | | **Data** | More menu | The app's own database (SQLite): its tables, their rows, and a **Structure** view of each table's columns. | The header shows whether a version is live (`vN live`) or the app is still a **Draft**, a **Save** button, and — once a version is live — **Open app**. A [visual review](#the-live-preview) runs against the surfaces the same way you read them: the rendered preview, its console, and its network activity. ## The Live Preview The Preview surface runs the **real** app, not a static mock. AI Studio mounts the app's npm project in the browser, installs or restores its dependencies, and starts its dev server, so the preview is the working app with its own front end and its own backend — an HTTP server backed by an in-browser database. Because the app runs a real project, an app that needs to remember what people enter gets a database of its own (see [Data an app keeps for itself](#data-an-app-keeps-for-itself)); there is nothing to set up. The assistant can also run a **visual review**: it reads the rendered preview, screenshots, runtime logs and network activity to decide whether the output matches your request or needs another edit. ### Starting the builder conversation over If an app-building session has gone in circles, **Clear chat history and try again** resets it. On a saved app this asks you to confirm first, because the builder conversation belongs to the **app** rather than to you — clearing it removes that history for everyone with access, and it cannot be undone. The app's own code is untouched. ## What a Published App Can Reach A published app reaches outside services and your Fours data from its own server code, with credentials it receives when it is published: - **Outside services** — an app can call another service's API with a key you store under its **Secrets**; the key reaches the live app when you publish (see [Publishing](#publishing)). - **Your Fours data** — through the Fours API, as described below. The app's own database is separate from both — see [Data an app keeps for itself](#data-an-app-keeps-for-itself). ### How a published app reaches your Fours data When you publish an app, Fours makes sure the app has an OAuth client of its own — creating it on the first publish — and gives its credentials to the published app. The app's server code calls the Fours API with that client. - **It has the Editor role.** The Fours API treats every call the client makes as coming from an **Editor**, for organization and personal apps alike, so the app's server code can do what an Editor can do through the Fours API. - **Console-only and Public apps both get it.** The [access setting](#who-can-open-a-published-app) decides who can open the app, not what its code can reach. - **It exists only for a published app.** AI Studio's preview has no client, so a call to the Fours API there fails with a message that API access is available after the app is published. - **It goes away with the app.** Deleting the app deletes its OAuth client. ```d2 direction: right classes: { box: { width: 220; style.border-radius: 8 } stop: { width: 220; style.border-radius: 8; style.stroke-dash: 3 } } publish: "You publish the app" { class: box } server: "Published app\nserver code" { class: box } client: "The app's own OAuth client\nEditor role" { class: box } api: "Fours API" { class: box } preview: "The same code in the\nAI Studio preview" { class: box } unavailable: "Unavailable until\nthe app is published" { class: stop } delete: "You delete the app" { class: box } removed: "OAuth client deleted" { class: stop } publish -> client: "creates it on the first publish" publish -> server: "delivers its credentials" server -> client: "client credentials" client -> server: "access token" { style.stroke-dash: 4 } server -> api: "calls as an Editor" preview -> unavailable: "no credentials" delete -> removed ``` ## Ownership and Sharing Custom Apps can be user-level or organization-level. | Ownership | Behavior | |-----------|----------| | **User** | Private to the creator (labeled **Personal** in the builder). Use this for personal tools or drafts. | | **Organization** | Shareable with teammates. Use this for team workflows and shared dashboards. | Who can create which kind of app depends on your organization role: - An organization **ADMIN** can create organization or personal apps; the wizard preselects **Organization**. - An **EDITOR** can create personal apps only — the wizard's **Organization** option reads *Only organization admins can create organization apps.* - A **VIEWER** can't create apps: **New App** is hidden, and the wizard says *You can't create apps*. ### Sharing an app Only organization-level apps can be shared, and the two ways to share combine: - **Share with the entire organization** — turn on **Share with entire organization** and pick a default role for every member. Org-wide sharing offers **Editor**, **User**, or **Viewer**. - **Share with specific users** — select a user and assign a role. Individual sharing offers **Admin**, **Editor**, **User**, or **Viewer** — **Admin** only when you are an organization ADMIN yourself. For anyone else the role picker leaves it out, and the server refuses the grant. A member's effective access is the higher of the two, so you can share an app org-wide as **Viewer** and grant **Editor** or **Admin** to the few people who maintain it. | Role | Run & interact | Edit & save | Manage sharing | Delete | |------|:---:|:---:|:---:|:---:| | **Owner** | Yes | Yes | Yes | Yes | | **Admin** | Yes | Yes | Yes | Yes | | **Editor** | Yes | Yes | No | No | | **User** | Yes | No | No | No | | **Viewer** | View only | No | No | No | The **Owner** is the app's creator, or whoever ownership was transferred to (see [Transferring ownership](#transferring-ownership)). A personal app can be deleted only by its owner; an organization app can also be deleted by anyone who holds **Admin** on it. Being an organization ADMIN does not count by itself: an org ADMIN who did not create the app needs an **Admin** share on it to delete it. When you open an app shared with you, its run panel shows an owner-and-role banner — even before the app has been built — and anyone below **Editor** (a **User** or **Viewer**) sees it **read-only**. See [Working with a Shared Resource](/insulin/getting-started/#working-with-a-shared-resource). ![Sharing an app — the org-wide toggle with a default role, plus per-user shares for granting higher permissions](images/11-insulin-share-app.png) #### Transferring ownership An organization app's **Share App** dialog opens with an **Owner** row naming the app's owner. Only the owner sees **Transfer ownership** beside it: 1. Click **Transfer ownership** 2. Pick the new owner from **Select new owner…** — the list shows only organization ADMINs other than you 3. Click **Transfer** You keep **Admin** on the app, so you can still edit it, manage its sharing, and delete it. A personal app has no Owner row and cannot be transferred. If you are no longer an organization ADMIN yourself, the transfer is refused and the message says why. #### Sending someone a direct link The Share App dialog also carries a **Copy link** button. It copies a deep link that opens the app's window straight away in the recipient's own Insulin workspace, so you can drop it into a message or an email instead of talking someone through where to click. The link also names the app's organization, so it opens Insulin in that organization even if the recipient usually works in another. Someone who isn't a member of it sees *This app’s organization is unavailable or you do not have access to it.* and an **Open Insulin without this app** button. :::warning The link is a pointer, not a grant. Whoever you send it to still needs access to the app through the sharing above — as the owner, through an individual share, or through org-wide sharing. Someone without access who follows the link will not be able to open it. ::: ### Finding and managing your apps Saved Custom Apps appear in the Custom Apps sidebar, split into **Org Apps** (organization-level apps shared with you) and **My Apps** (your personal apps). A search box filters both lists by name or description. Right-click any app in the sidebar for a context menu. Which entries appear depends on your role **on that app**, so the same menu is shorter on an app someone else owns: | Action | What it does | When it appears | |--------|--------------|-----------------| | **Edit App** | Opens the app in the builder. | Editor or above. | | **Add to Desktop** | Pins the app to the Insulin desktop as an icon so you can launch it directly. | Always. | | **Share App** | Opens the Share dialog. | Organization apps only, and only for an admin or the owner. | | **Delete App** | Permanently removes the app. | The owner; on an organization app, also an Admin. | That is why a personal app you created shows **Edit App**, **Add to Desktop** and **Delete App** but no **Share App**, while an organization app you are only a member of may show nothing but **Add to Desktop**. ![The Custom Apps sidebar — a search box above the New App button, the Org Apps and My Apps groups with their counts, and a right-click context menu on a personal app offering Edit App, Add to Desktop and Delete App](images/27-custom-apps-sidebar.png) Deleting an app starts a cleanup of everything it had — its source and saved versions, its database and data, and the published app. The **Cleanup** list at the bottom of the sidebar follows each one, from *Cleanup running* to *Cleanup complete* — or *Cleanup failed — resources may remain*. An organization ADMIN sees every app deleted in the organization; everyone else sees the apps they deleted. ## Publishing An app becomes a working tool for other people by being **published**. Publishing takes a **saved version** and puts it in production, giving the app its own live URL. Until you publish, the app runs only in AI Studio's preview. Open the **Publish** panel from the Studio header. It has two parts: - **Production** — what is live now: the version, when it was published, and its URL. A publish in progress (even one started in another tab) shows its steps here, and a failed one shows why while leaving whatever was already live untouched. Anyone who can edit the app can **Cancel** a publish while it is still building or deploying; once the new version has deployed and is only waiting to go live, publishing another version replaces it instead. If a deployment hasn't been confirmed yet, the panel says the version *may already be serving* rather than calling it live. - **Versions** — every saved version, each with its own **Publish** button. Publishing is one step per version — *Publish vN to production* — so publishing an earlier saved version is also how you roll an app back. Only saved versions can be published, so save first to include your latest changes. Publishing is also what delivers the app's **secrets** — the owner's own credentials for the app. Secrets are managed on the [Settings surface](#studio-surfaces); a publish is what pushes them to the live app, so adding or changing a secret means re-publishing. Removing one also asks for it to be removed from the live app straight away: the Secrets section shows *Live removal is requested; its progress appears below.* and tracks it under **Live removal requests**, with **Retry removal** if it fails. Where that isn't available, it shows *The live app keeps it until you publish again.* Only the app's **Owner** or an **Admin** on it can add or remove a secret — and *Anyone who can edit and publish this app can read these values from its environment. Share it accordingly.* :::info Publishing may not be available in every environment. When it is not, the panel says so, and you can keep building and saving in AI Studio. ::: ### Who can open a published app **Settings → Access → Published access** decides who can open the app once it is published: | Setting | Who can open the published app | |---------|-------------------------------| | **Console-only** | Only people signed in to the Fours console who have access to the app. A new app starts here. | | **Public** | Anyone with the published URL. Sharing still decides who can edit the app. Apps created before this setting existed are Public until someone changes them. | Only the app's **Owner** or an **Admin** on it can change the setting; everyone else sees it read-only. Switching a Console-only app to Public asks you to confirm in **Allow public access?**, because anyone with the URL could then open it without signing in. The change takes effect at the next publish — **Live access** shows what the published app uses now — so publish a saved version, then check the publish status to confirm the change is live. ## Running a Saved App A saved app runs by being [published](#publishing). Once a version is live, opening the app shows the running app in the **runner window**: the live app is embedded directly in the window (in a credentialless iframe), so you use it without leaving Insulin. If the app has not been published, the runner window says **Not published yet** — *Publish a saved version from the builder to give this app a live URL* — instead of a blank screen. Publish a saved version to bring it to life. Where an app cannot be embedded, the runner window shows the app's live URL with an **Open app** button that opens it in a new tab instead. A [Console-only](#who-can-open-a-published-app) app opens in the runner window under your own Fours sign-in — the window shows *Opening* and the app's name while it signs you in. This needs a browser that supports credentialless iframes, such as Chrome or Edge; in another browser the runner window asks you to use one of those. Opening a Console-only app's address directly takes you to the app inside the Fours console instead. Your access is re-checked every few minutes, so if it is removed while the app is open, the app stops within about five minutes with *Your access to this app ended. Open it again.* While a publish that changes how the app is reached — its access setting or its address — is waiting to be confirmed, the runner window shows **Deployment is not confirmed** instead of the app; check the publish status in AI Studio before opening it. If you can edit the app, an **Edit app** button above it opens the app in AI Studio. ### Data an app keeps for itself An app can keep data of its own. Ask the builder for an app that has to remember what people enter — a request tracker, a to-do list, an intake form — and it gives the app a database of its own, separate from every other app's. The database is created the first time the app needs it; there is nothing to set up. ```d2 direction: right classes: { box: { width: 230; style.border-radius: 8 } } first: "The app first needs\nto store something" { class: box } created: "Its own database\nis created" { class: box } change: "You save new code,\nor restore a version" { class: box } migrate: "The app's migration runs again\nExisting data is not automatically reset;\nthe migration may change it" { class: box } remove: "You delete the app" { class: box } gone: "App and data unavailable\nDatabase removal scheduled" { class: box } first -> created -> change -> migrate migrate -> change: "next change" created -> remove -> gone ``` What happens to that data as the app changes: - **Saving new code** — existing data is not automatically reset. The app's migration, its own setup step, runs again on each save that changes the code and may change the data already stored. - **A migration that fails** — the save is refused and the app keeps its previous version, but any database changes the migration made before it failed are not undone. - **Restoring a version** — brings back that version's code, not its data (see [App History and Restore](#app-history-and-restore)). - **Deleting the app** — makes the app and its data unavailable, and schedules removal of its database. Treat the data as gone. The **Cleanup** list in the Custom Apps sidebar shows the removal's progress — see [Finding and managing your apps](#finding-and-managing-your-apps). Once the app is published, **Settings → Database** lets app admins — the app's **Owner** or an **Admin** on it — browse that production database read-only: pick a table and page through it 25 rows at a time (*Read-only production data. Pages reflect live data. Binary values are omitted and long text is shortened.*). Anyone else sees *Only app admins can inspect production data.*, and until the published app has a database the section says *No production database is available yet.* This database is separate from your Fours data, which a published app reaches through the Fours API — see [How a published app reaches your Fours data](#how-a-published-app-reaches-your-fours-data). ### App History and Restore The builder header carries a **History** button, which opens **App History — **. Every save that changes the app's **code** is snapshotted. Saves that do not are deduplicated away — saving the same source again, or editing only metadata, does not mint a version — so the list is a record of the app actually changing rather than of how often you pressed Save. The newest **50** versions per app are kept. From the list you can **preview** any version, then **Restore** it behind a two-step confirmation. **Discard draft to vN** puts that saved version back in the editor without creating a new version. AI Studio's working draft is shared by everyone editing the app, so this replaces it for every collaborator — the confirmation reads *This replaces the shared draft for every collaborator with vN. Unsaved edits will be lost. No new saved version is created; the live app stays as it is.* Click **Confirm discard** to go ahead. :::note **Restore rolls forward; it never deletes.** Restoring creates a **new** version whose source is the snapshot's, and that new version is saved like any other. Nothing between the snapshot and now is removed, so a restore is itself undoable by restoring the version you were on. A restore brings back the snapshot's code, not its data: data the app has stored for itself is not rolled back or automatically reset, and the restored version's migration runs again and may change it (see [Data an app keeps for itself](#data-an-app-keeps-for-itself)). ::: Read-only roles can list and preview versions, but cannot restore or discard. ### When an app fails to render If AI Studio can't start the app in the preview, the Preview surface shows **Preview couldn't start** with the error the runtime reported, instead of a blank screen. ### Reading and exporting an app's data Tables and charts generated by the builder come with their own controls, so you can take the numbers out of the app without asking anyone to re-run a query. | Widget | Control | What it does | |--------|---------|--------------| | **Table** | **Download CSV** | Exports the rows currently shown, using the columns currently visible. Appears whenever the table has data. | | **Table** | Column headers | Click a header to sort. Clicking cycles ascending → descending → back to the table's own order; an arrow on the header shows the current direction. | | **Table** | **Columns** | A checkbox list for showing and hiding columns. This one is opt-in — it appears on tables the app was built with a column picker on. | | **Chart** | **Download SVG** | Saves the chart itself as a vector image you can drop into a deck or a doc. | | **Chart** | **Download CSV** | Saves the data behind the chart. Greyed out when the chart has no data. | Both chart exports live behind the **≡** button in the chart's header, which appears on charts plotted over time. :::info The Download CSV control on tables is generated into the app, so it reaches apps built from now on. An older saved app may not have it until you regenerate it in the builder. ::: ## How Custom Apps Fit With Insulin Custom Apps work best alongside the rest of Insulin: - Use [Agents](/insulin/agents/) to define the expertise behind a workflow - Use [Marketplace](/insulin/marketplace/) to install reusable agents or skills before building - Use [Jobs](/insulin/jobs/) for scheduled or event-triggered runs - Use [Channels](/insulin/channels/) when teammates need to discuss app output with agents - Use [knowledge bases](/insulin/knowledge-base/) and connected systems to ground the app in your organization's data --- Source: https://doc.fours.com/insulin/inbox/ # Inbox Inbox is an email-triage workspace that connects your mailbox, labels incoming mail the way your rules say, and drafts replies in your writing style — plus rules that can react to a CRM event. Nothing leaves your mailbox until you approve it, unless you author an auto-send rule yourself. --- ## What Is Inbox? Inbox is a built-in Insulin app pinned to the desktop Dock. Once you connect a mailbox, Insulin watches for incoming email, checks each message against your rules, and — when one matches — produces something for you: a drafted reply, a Slack notification, or a CRM action. Drafted replies and CRM actions wait in the **Approvals ▸ Pending** queue where you read, edit, and confirm them. A Slack notification is only a heads-up sent straight to you, and an auto-send rule you write yourself sends its reply without stopping in the queue unless its pre-send check holds it back. Prefer video? Watch a quick overview: The whole feature is built around one safety promise: :::warning **Insulin never sends email on its own.** Every AI-generated reply waits in the **Approvals ▸ Pending** queue until you review it, and pressing **Send** requires a separate confirmation step because sending cannot be undone. The only exception is an **auto-send rule** — a rule you explicitly author that authorizes sending without review, within [strict limits](#when-an-auto-send-rule-may-send). Nothing sends automatically unless you have created such a rule yourself. ::: :::info Inbox supports **Gmail** and **Outlook**. Only **one** of them can be the Inbox mailbox at a time — see [Switching between Gmail and Outlook](#switching-between-gmail-and-outlook). ::: ![The Inbox app — the sidebar with Approvals expanded to Pending (with its count badge) and History, Mails expanded to its views, and Settings below, beside the mail list and reading pane](images/21-inbox-mails.png) ## Opening the Inbox App Open Inbox from the **Inbox** tile pinned to the desktop Dock, or from the **Search apps…** launcher in the System Bar. Like other workspace apps it opens as a resizable window. A left sidebar navigates the app: | Entry | What it holds | |-------|---------------| | **Approvals** | A group with two entries. **Pending** is everything waiting on you — the tab Inbox opens on, carrying a live count badge of the items in the queue. **History** is the record of everything Inbox has executed: every sent email and every CRM action, with who authorized it, when, and the recorded outcome. | | **Mails** | Your mailbox, mirrored. Expands to the views **Inbox**, **Starred**, **Sent**, and **Drafts**. | | **Settings** | A collapsible group with **Account** and **Rules**. | **Mails** opens on **Inbox**. Labels are declared on rules (see [Labels](#labels)) and appear as chips on the mails carrying them, like Gmail's — they are not a navigation level. **Drafts** lists your provider's drafts live, and archiving mail in your mail client simply removes it from **Inbox** here — nothing is deleted. The window's address follows what you open: each email under Mails and each item under Approvals ▸ Pending gets a link of its own, so refreshing, going back, or opening a saved link — even in an Inbox window that is already open — returns you to that same email. Links saved from earlier versions of Inbox still open the right view. ## How an Email Becomes an Action ```d2 direction: down mail: "Incoming email\nGmail or Outlook" crm: "CRM event\nSalesforce · HubSpot · Dynamics 365" match: "Rule match\neach rule's filter, then context from the\nintegrations you connected" draft: "Email draft" crmaction: "CRM action" slack: "Slack DM to you" { shape: rectangle; style.stroke-dash: 3 } auto: "Auto-send\nonly from a rule you wrote, on one exact filter,\nwith no customer, knowledge-base or integration data" { shape: rectangle; style.stroke-dash: 3 } check: "Pre-send check" { shape: diamond } gate: "APPROVALS ▸ PENDING\nyou read it, edit it, confirm it" sent: "Sent from your mailbox" ran: "Agent runs it live in the chat rail\nlimited to that one CRM" mail -> match crm -> match match -> draft match -> crmaction match -> slack: "notification only" { style.stroke-dash: 4 } match -> auto: "bypasses the gate" { style.stroke-dash: 4 } draft -> gate crmaction -> gate auto -> check check -> sent: "passes" check -> gate: "held for review" { style.stroke-dash: 4 } gate -> sent: "Send, then confirm" gate -> ran: "Run in chat" ``` Everything on the solid path stops at **Approvals ▸ Pending**. The two dashed outputs are the exceptions: a Slack notification only tells you something happened, and auto-send exists only if you wrote a rule that asks for it — and even then a pre-send check can hand the reply back to the queue. ### When an auto-send rule may send An auto-send rule is the one path where Insulin sends mail without you, so it is held to a stricter standard than a rule that drafts for review: - **One exact filter decides whether it fires.** The rule has to compile to a single condition on the sender's address, the sender's name, the subject, or the body — *contains*, *starts with*, *ends with*, *equals*, or a regular expression — and that condition alone decides. The AI never judges whether an auto-send rule applies to an email. Anything that could match every email is refused, including a pattern that would match an empty field. - **No outside context goes into the reply.** A generated reply is written in your writing style from the incoming message and the rule's own instructions — with no customer or billing data from Fours, no knowledge-base passages, and no lookups in your connected integrations. A rule with pinned canned text sends your saved words instead. If you ask an auto-send rule to look something up (its **Context sources**), it never sends: every reply it produces waits in **Approvals ▸ Pending** instead. - **A last check runs before anything leaves.** A generated reply is held for review when the AI that wrote it flags it as needing a human, or when a fixed check on its subject and body finds an empty message; something that looks like a card number, a US Social Security number, or a private key; or a link or email address that is not the sender's own address or at the sender's domain. A canned reply's body is your own text, but the subject it repeats from the incoming email gets the same check. A held reply lands in **Approvals ▸ Pending** like a draft from any other rule. When it was held for its context sources or by the fixed check, it carries a note saying so — see [Before you press Send](#before-you-press-send). Nothing is lost; the send simply waits for you. Auto-send rules can only be written on the **Rules** page: the [Inbox chat rail](#the-inbox-chat-rail) refuses to create one. ## Connecting a Mailbox Open **Settings → Account** and find the **Email source** section. Inbox does not run its own OAuth flow — it reuses the connection you set up under Integrations. Each provider has its own card, and there are two paths to enabling it: 1. **Already connected** — If you have already connected [Gmail](/integrations/google-mail/) or [Outlook](/integrations/microsoft-outlook/) through Integrations, the card shows an **Enable Inbox for Gmail** / **Enable Inbox for Outlook** button. Clicking it health-checks your access, registers the mailbox webhook, and starts building your [writing style](#writing-style). 2. **Not connected yet** — The card shows a **Connect Gmail** / **Connect Outlook** link that takes you to **Settings → Integrations**, where the standard connection lives. Once connected, return to this page and click **Enable Inbox for …**. A connected card shows **Connected as** your mailbox address, plus an **Inbox enabled** badge once Inbox is running. :::info Only **one** email provider can be the Inbox mailbox at a time. While one holds the slot, the other card shows either a **Switch to …** action (if that provider is already connected under Integrations) or the note *"Only one email provider can be connected at a time."* ::: ### Account Lifecycle The active provider's card exposes two lifecycle controls with very different effects on your data: | Action | What it does | Effect on your data | |--------|--------------|---------------------| | **Disable** | Pauses Inbox — it stops receiving and processing any new email. | Mail Inbox has already processed is **kept**. Re-enable anytime with **Enable**. | | **Disconnect…** | Immediately deletes the email Insulin has stored and resets Inbox to a never-connected state. | Some things are deleted, some are kept — see [What Disconnect does to each thing](#what-disconnect-does-to-each-thing). Your **actual mailbox is not touched**. This **cannot be undone**. | :::warning **Disconnect is destructive, and it is not a full erasure.** It permanently removes Insulin's copies of your triaged email, and it clears your writing style. Disconnect does not delete or modify any message in your real Gmail or Outlook mailbox — what Insulin writes there is described under [Drafts in your Gmail Drafts folder](#drafts-in-your-gmail-drafts-folder) — and it does not remove the rules you defined — those survive and apply again if you reconnect. A minimal, content-free record of each processed message is also kept for de-duplication and audit. ::: #### What Disconnect does to each thing | What | Disconnect | Notes | |------|------------|-------| | Stored email records, their AI drafts, and the labels Inbox applied to them | **Deleted** | Hard-deleted. This is the bulk of what Insulin holds about your mail. | | Your writing style | **Cleared** | Reset to empty. Reconnecting rebuilds it from the mailbox you reconnect. | | Processing history (execution records) | **Redacted but retained** | The message content, subject, classification and your mailbox address are stripped. A minimal record with no message content is kept for de-duplication and audit. | | Your rules, including the labels they declare | **Untouched** | Every rule you wrote survives and runs again if you reconnect — only the labels *applied to deleted messages* go away with those messages. | | Your knowledge-base selection | **Untouched** | | | Your real Gmail or Outlook mailbox | **Untouched** | Disconnect does not delete or modify any message in the mailbox itself. The only messages Insulin creates are its own mirrored drafts — see [Drafts in your Gmail Drafts folder](#drafts-in-your-gmail-drafts-folder). On mail you received it only ever changed labels and read state. | ### Switching between Gmail and Outlook When one provider is active and the other is already connected under Integrations, the inactive card offers **Switch to Gmail…** / **Switch to Outlook…**. :::warning **Switching permanently deletes the old provider's mail.** The dialog spells this out: your current provider's emails — including AI-applied categories, drafts, and classification history — are permanently deleted, and this cannot be undone. Your writing style is rebuilt from the new mailbox. To confirm, you must type the literal word `SWITCH` into the confirmation box; the **Switch** button stays disabled until it matches exactly. ::: ### If you disconnect the integration itself Disconnecting the underlying Gmail or Outlook integration (under **Settings → Integrations**, outside Inbox) does not purge your Inbox data immediately. Insulin starts a **7-day grace period**: reconnect the integration inside that window and nothing is lost. If the integration is still missing after seven days, the purge above runs — the stored email records are hard-deleted and Inbox resets to a never-connected state. The seven days start only once Insulin has confirmed the integration really is gone. If that check cannot run — during a provider outage, for example — the countdown does not begin. Once it has begun it runs on the calendar, but nothing is deleted until a check confirms the integration is still missing, so an outage can only delay the purge, never bring it forward. ![Inbox Settings → Account — the Email source section with Gmail enabled beside the Outlook card and its Switch to Outlook action, the AI model list, the Salesforce, HubSpot and Dynamics 365 triggers, and the Writing style card](images/22-inbox-settings-account.png) ## Approvals ▸ Pending **Pending**, under **Approvals**, is the queue of everything Inbox has produced for you and is holding until you act. It is the tab Inbox opens on, and its sidebar badge counts what is waiting. Once you act, the item leaves Pending: sending or running it moves its record to [**History**](#approvals--history); archiving it discards the item without adding a History row. Use the search box — *Search by subject, sender, recipient, domain or rule…* — to narrow the queue. It matches an item's subject, the sender's name or address, its summary, the draft's body, any address in To or Cc, and the name of the rule that produced it, so typing a customer's domain such as `acme.com` finds everything with that customer — including a new outbound draft, whose customer appears only as a recipient. The chevron button beside the box holds the filters you can't type: an exact rule (**All rules**) and the **draft email** / **crm action** item types. It shows how many filters are active, and opens by itself whenever one is already narrowing the queue. ### Reviewing a drafted reply Selecting a reply draft opens a compose pane on the original thread: - **To** is editable, and a chevron next to it reveals a **Cc** field so you can copy other people on the reply. **More ▸ Reply all** pre-fills Cc with the thread's wider audience (minus yourself). - The thread history sits above the editor so you can read what you are replying to. - The reply body is inline-editable and saves when you click away from the field. - **Attach** stages files onto the reply (Gmail only — see [Attachments](#attachments)). #### Drafts in your Gmail Drafts folder On a Gmail mailbox, Insulin mirrors each AI draft — including one the [chat rail](#the-inbox-chat-rail) creates for you — into your Gmail **Drafts** folder so it appears where you already work. It **creates** the Gmail draft when the reply is generated, **updates** it when you edit the draft in Inbox, and **deletes** it when you send or archive the draft from Inbox. Those drafts are the only messages Insulin creates in your mailbox. On mail you received it changes only labels and read state — never the message content, and it never deletes one. Outlook drafts are not mirrored. These Gmail copies, and the labels and stars Inbox mirrors to Gmail, need your Gmail connection to carry Gmail's `gmail.modify` permission. Without it nothing is copied to Gmail, but Inbox itself works as before: drafts still wait in **Approvals ▸ Pending**, and labels and stars still show here. If your Gmail connection was authorized without a permission Fours' Gmail connection now asks for, **Enable Inbox for Gmail** under **Settings → Account** fails with **Gmail health check failed**, names the missing permission, and asks you to disconnect and reconnect Gmail in **Settings → Integrations**, then try again. | Action | What it does | |--------|--------------| | **Save** | Persists your edits to the draft without sending. | | **Send** | Sends the reply (see the confirmation step below). | | **Archive** | Drops the draft out of the queue; the mail itself stays in your mailbox and under **Mails**. | | **More** | Reply all. | **Sending is a two-step gesture.** Clicking **Send** opens a **"Send this reply?"** confirmation dialog, and you must confirm there before the reply actually goes out. This second step exists because sending is irreversible — there is no unsend or recall. #### Before you press Send The reply pane shows what the draft was written from, so you can check it before it goes out: - **Why it is here.** A reply that an auto-send rule held back says so beneath the draft — *"This rule asks to send automatically, but it also reads customer context — so the draft comes here for review instead of being sent."* when the rule names context sources, or *"The pre-send check flagged this reply, so it was queued for review instead of being sent."* when the fixed check tripped. - **Customer** — when the draft was written with a customer lookup, who Inbox matched the sender to and what it knew about them. See [The Customer block](#the-customer-block). - **Text the AI read** — the exact text the AI was given, inside the thread history. See [Checking what the AI read](#checking-what-the-ai-read). - **Send waits for the email.** **Send** stays disabled until the email you are replying to has loaded. If your mail provider won't return it, the footer reads *"This email can't be read from your mail provider, so there is no way to check what the AI replied to."* with a **Retry** button beside it. ### The Customer block When your rules run on an email, Inbox tries to match its sender to one of your Fours customers — the sender's address to a contact, the contact to a customer — and a draft for review is written with what it found. The **Customer** block shows that match on the reply pane and in the **Mails** conversation view: | What it shows | What it means | |---|---| | The customer's name, a badge for its cloud marketplace, and *via* the matched contact | Matched. Below it: how many of the customer's entitlements are active (with a few of their names), and — when there are any — its open offers with the next expiry and its unpaid invoices with the amount due per currency and the oldest due date. | | *"3 customers share this contact — no single customer was matched."* (with the actual count) | Ambiguous. More than one customer claims this contact, so no customer's data was used. | | *"This sender is not a known contact in your organization."*, *"This contact is not linked to a customer."*, *"The email carried no sender address to match."*, or *"The customer lookup failed — nothing was matched for this sender."* | Not matched, with the reason. The draft was written without customer data. | The block is a **snapshot** taken when the rules ran — what the AI knew when it wrote the draft, not today's figures — and it is read-only. Replies an auto-send rule writes use no customer data, so they carry no Customer block. The exception is a rule held back for its context sources: its generated draft is written like any other draft for review, customer lookup included. ### Checking what the AI read A formatted email usually carries two versions of its body, written separately by the sender: a plain-text version and an HTML one. Your mail client shows you the HTML version; the AI reads the plain one. They normally say the same thing — but a sender can hide text in the version you don't see. So every HTML message in the thread history carries a collapsed **Text the AI read** line: open it to see exactly the text the AI was given. When the plain text contains a passage of about twenty words or more that the visible email doesn't show — text hidden from view counts as not shown — that message shows a warning in place of the line, *"⚠ Possibly malicious email — hidden text differs from what you see. Check what the AI read:"*, followed by the text. If it is the message you're replying to, it is opened for you even when a newer message sits above it. Read that text before you approve a reply. The check only decides how prominently the text is shown; it never blocks anything. It appears wherever the thread history does: on the reply pane, in the **Mails** conversation view, and in the reply composer. ### Reviewing a new outbound draft A rule fired by a CRM event — or a draft the AI chat rail created for you — produces a brand-new email rather than a reply. That one opens as a compose pane with an editable **To**, **Subject**, and **Draft** body, and the same **Save** / **Send** / **Archive** actions. The confirmation dialog reads **"Send this email?"**. ### Running a CRM action A rule can also produce a **CRM action** — a written instruction such as *"update the CRM with a short summary of the latest email thread."* It appears in the queue as its own block showing the instruction and a **Run in chat** button. :::info **A CRM action is never executed silently.** Nothing happens until you click **Run in chat**, which hands the instruction to the agent in the [Inbox chat rail](#the-inbox-chat-rail) and lets you watch it run. Once run, the item leaves the queue and the button is replaced by *"Sent to chat"*. Because the item leaves the queue, its record moves to **Approvals ▸ History** (and to the email itself, whose **CRM action** section shows the same block). The record has two parts. The **receipt** is written the moment you click: the instruction, **Authorized by** *you*, and when. The **outcome** is written when the agent finishes: whether the CRM write **succeeded or failed**, a short summary of what it did, and the records it created or updated. If the agent never gets to record an outcome — a tool failure, a denied action, a closed tab — History shows *outcome not recorded* rather than a fabricated success, so the authorization and the result are always told apart. ::: **A Run is limited to the CRM the action came from.** When you click **Run in chat**, Insulin works out what the run may touch from the stored action, not from your browser. The agent can use only the connection the action was raised against — the Salesforce, HubSpot or Dynamics 365 connection whose event fired the rule — plus the step that records the outcome. Your other integrations, the Inbox mail tools, rule creation, jobs, the browser, the file sandbox, memory and goals are out of reach, and the agent can't stop to ask you a question. The limit covers that one run: a message you type in the rail afterwards is an ordinary rail conversation again. ```d2 direction: down card: "CRM action card\nApprovals ▸ Pending" scope: "Insulin sets the run's reach\nfrom the stored action" agent: "Agent in the Inbox chat rail" crm: "The one CRM connection\nthe action came from" rec: "Outcome recorder" hist: "Approvals ▸ History\nreceipt + outcome" other: "Out of reach for this run\nother integrations · mail tools · rules\njobs · browser · sandbox · memory · goals" { style.stroke-dash: 3 } card -> scope: "Run in chat" scope -> agent: "one scoped run" agent -> crm: "reads and writes" agent -> rec: "when it finishes" rec -> hist scope -> other: "withheld" { style.stroke-dash: 4 } ``` - **An action queued before Insulin recorded its CRM connection can't be run.** Instead of **Run in chat**, its card reads *"Queued before this action recorded its CRM connection, so it can't be run — trigger the rule again to raise it."* - **Several Runs go one at a time.** Click **Run in chat** on more than one action and the rail runs them in order, each waiting for the previous one to finish. - **A failed Run offers no Retry.** The CRM write may already have happened before the reply stopped, so instead of **Retry** the error card says *"This CRM action may already have run — check the record in your CRM, or the action's outcome in Approvals, before running it again."* - **Only that Run records the outcome.** An action's outcome in **Approvals ▸ History** can be written only by the run launched from that action's own card, and it always lands on that action. ### Approvals ▸ History **History**, the second entry under **Approvals**, is the durable record of everything Inbox has executed — it is not the chat transcript, and it outlives it. It lists, newest first: | Entry | What it shows | |-------|---------------| | **CRM action** | The deal it belongs to, the instruction, its status, the receipt (**Authorized by**, when), a link to the chat-rail conversation it ran in while that conversation exists, and the recorded **outcome** — succeeded or failed, the agent's summary, and the CRM records written. | | **Sent email** | The subject, the recipients, and who pressed **Send** and when. | For a CRM action the recorded outcome lists each record the agent wrote and, where the agent was able to read that record, its field values **before and after** the write — so you can see what changed, not only that something did. A record whose prior values could not be read is shown as **not captured** rather than as an empty change. Use the search box to narrow the list by deal name, instruction, or outcome summary. **Export** downloads the ledger for a date range as a CSV — each row with its receipt, outcome, and any captured before/after diff — so a reviewer can pull the record without asking engineering. A very large range is capped: the file then ends with a truncation marker, so narrow the dates and export again. CRM-action records are kept for **two years** from the moment they were authorized and then removed; sent-email records follow the mailbox's own retention. ### Attachments | Limit | Value | |-------|-------| | Files per message | Up to **3** | | Size per file | Up to **5 MB** | :::warning **Attachments are not supported on Outlook, in either direction.** Incoming Outlook messages show no attachment list in Inbox and their files cannot be downloaded from it, and an Outlook send that carries attachments is refused with an error rather than silently going out without them. On an Outlook mailbox the **Attach** control is therefore not shown. Gmail handles attachments normally in both directions, including files forwarded from the original message. ::: ![The Inbox on Approvals ▸ Pending — the queue with its search box and rule filter, the selected AI draft with its editable To and its subject, the draft body and its evidence, the Save / Send / Archive actions, and the chat rail on the right](images/20-inbox-approvals.png) ## Mails **Mails** mirrors your mailbox. Pick one view at a time from the sidebar: | View | Shows | |------|-------| | **Inbox** | Mail in your provider's inbox. | | **Starred** | Mail you starred — in your mail client or here. | | **Sent** | Mail you sent. | | **Drafts** | Your provider's drafts, listed live. On Gmail, open one to edit or send it — see [Editing a draft in Mails](#editing-a-draft-in-mails). | | *a label* | Every mail carrying that label, across the views above. One entry per label your rules declare. | The page has three panes: a searchable mail list, a conversation view, and the [AI chat rail](#the-inbox-chat-rail). The **conversation view** shows the subject once, the number of messages, the labels applied to it, and a status badge. Older messages in the thread are collapsed and load when you click them. - **Archive** / **Unarchive** sit in the conversation header, because they act on the whole conversation. - **Reply**, **Reply all**, and **Forward** sit under the newest message. If Inbox has already drafted a reply for that mail, **Reply** takes you straight to that draft in **Approvals ▸ Pending** instead of opening a blank composer. - In the reply composer, **AI generate** writes a draft in your learned writing style, which you can then edit before sending. The conversation view also carries the [Customer block](#the-customer-block) for mail your rules processed and, on HTML mail, the [Text the AI read](#checking-what-the-ai-read) line in each message. If Gmail is briefly unavailable or rate-limits Insulin while a message is being processed, Inbox tries that message again on later deliveries — three attempts in all — before giving up on it. A message it gave up on shows a **Failed** badge in the conversation view and has no draft; you can still reply to it yourself. A permanent error, such as a revoked connection or a deleted message, is not retried. :::info Email bodies are fetched live from your provider each time you open a message, and the **full body is never stored** by Insulin. What Insulin does retain per message: the subject, sender, recipients and timestamps; the short preview line your provider returns with the message (Gmail's snippet, Outlook's body preview), which is what the mail list shows; the labels applied; any structured **extraction** (for example a drafted reply's subject and body); the AI drafts themselves and their edit history; the **Customer** snapshot — which customer the sender was matched to, and that customer's entitlement, offer and invoice summary at the time; a **thread summary** when you request one; and the rule-trace records that explain which rules ran. ::: ### Searching mail **Mails** has one search box above the list — *Search by subject, sender, recipient or domain…*. It searches on the server, so a match on a page you haven't scrolled to yet is found rather than hidden. The match is plain text, ignoring case, across the subject, the sender's name and address, the preview line, and every address in To and Cc — so typing a customer's domain such as `acme.com` finds every mail to or from that customer. **Approvals ▸ Pending** has the same box, which also matches draft bodies and rule names; see [Approvals ▸ Pending](#approvals--pending). The **Drafts** view lists your provider's drafts instead and has no search box. ### Editing a draft in Mails On a Gmail mailbox, **Mails ▸ Drafts** lists the drafts in your Gmail **Drafts** folder — including the ones Inbox mirrored there — and selecting one opens it in a composer: | Control | What it does | |---------|--------------| | **To**, **Cc**, **Subject** and the body | Edit the draft in place. | | **Save** | Writes your edits back to the draft in Gmail. | | **Send** | Asks you to **Confirm send** — *"This sends from your mailbox immediately."* — then sends the draft from your mailbox. If you changed it, your edits are saved first, so what goes out is what is on screen. | | **Open in Gmail** | Opens the same draft in Gmail. | A few cases work differently: - **A draft with attachments** can only be sent as it is: *"This draft has attachments, which can't be kept through an edit here. Send sends it exactly as saved — to change it, open it in Gmail."* - **A draft that changed in Gmail** after you opened it is not sent. The pane says so, and **Reload draft** loads the latest version. - **A draft Inbox mirrored from Approvals ▸ Pending** completes that approval when you send it here: it leaves **Pending** and is recorded in **History** as a sent email. If Approvals already sent it, the send is refused — *"This email was already sent from Approvals — this draft is a leftover copy. Delete it in Gmail."* - **Without permission to change drafts**, **Save** and **Send** show a message instead: either to disconnect and reconnect Gmail in **Settings → Integrations**, or that editing and sending drafts from Insulin isn't enabled for your workspace's Gmail connection yet — then open the draft in Gmail. See [Drafts in your Gmail Drafts folder](#drafts-in-your-gmail-drafts-folder). - **On Outlook**, the view reads *"Live drafts aren't available for this mailbox provider yet."* As with **Send** on an approval, sending from here is a deliberate two-step action of yours — Inbox never sends a mailbox draft on its own. ## The Inbox Chat Rail Every Inbox page carries a chat rail down the right-hand side, headed **Chat with your inbox**. It is not the Chat app in a narrow window — it is a conversation about the mail you are looking at. - **It is always there.** Every page — Pending, History, Mails, Rules, Account — mounts the same rail. Collapse it with the button in its header; a small reopen button then appears at the top-right of the page. - **It resizes.** Drag the handle on its left edge. The rail can be anywhere between **15%** and **45%** of the window width; it starts at about 30%. - **It has its own conversation.** The rail runs the built-in Insulin agent on a thread dedicated to Inbox, separate from the [Chat](/insulin/agents/#conversations) app — so your inbox conversation never mixes into your general chat history. Type `/clear` to start a fresh one. - **It knows what you are looking at.** Every message you send carries the current page as context: which tab you are on, which label is selected, which mail is open, and the mails currently visible in the list. Ask *"what needs a reply here?"* and it answers about the screen in front of you, not about your mailbox in the abstract. - **It can act.** Beyond reading, listing, searching, and counting your mail, the agent can **create an email draft** for you (it lands in **Approvals ▸ Pending** like any other draft) and **create a rule** from a plain-English description — any rule except one that sends automatically, which you can only write on the **Rules** page. It is also where a **Run in chat** CRM action executes, within the [limits of that run](#running-a-crm-action). ## Rules Rules control what Inbox does for you — which messages get a drafted reply, which CRM events produce work, and what context the AI pulls in. Open **Settings → Rules**. The left panel lists your rules, with a search box and a **New** button. Every row carries an enable switch and a delete button, so turning a rule off never requires opening it. Inbox ships no rules of its own — nothing is drafted until you create a rule that asks for it. ### Describing a rule The rule editor is **natural-language first**. You fill in two fields, and a panel below them follows what you write: 1. **Rule name** — optional. Leave it blank and Insulin generates one for you. 2. **Describe the rule in natural language** — a plain-English box where you say what should happen, for example *"When a new email arrives that needs a reply, draft a reply for me to review before it is sent."* 3. **Integrations** — the integrations your description names, which are the ones **Save** lets the rule search when it runs. See [Choosing integrations](#choosing-integrations). Then click **Save**. That single click both turns your description into a structured rule and saves it — there is no separate generate step. Saving runs an AI model and takes a few seconds; an inline notice asks you not to refresh while it works. :::info **Save fails and nothing is written when the rule is missing a prerequisite.** This is deliberate: saving anyway would have replaced the rule's filter with one that matches every email. It is not only the AI model. Save checks everything the rule needs, and each missing piece appears as its own row with the reason and a link straight to the setting that fixes it: | Check | Fails when | | ----- | ---------- | | **AI model** | No model is available to interpret the description. | | **Mailbox** | No mailbox is connected, or one is connected but not enabled. | | **CRM** | The rule uses a CRM, and it is not connected — or is connected with its trigger disabled. | | **Slack** | The rule delivers to Slack, and Slack is not connected. | | **Context sources** | A context source the rule names is missing or cannot be resolved. | All of these are **user-level** integrations, so the fix links point at **Settings → Integrations → User Integrations** or your Account page — connecting one at the organization level does not satisfy them. ::: Editing a rule works the same way — change the description and click **Save** again. Changing only the name just renames it; the rule's behavior is left alone. ### Choosing integrations The **Integrations** panel under the description shows each integration your description names as a chip. A chip marked **Not connected** is one you haven't connected yet under **Settings → Integrations**. The panel and the description stay in step: - **Name an integration in the description** and its chip appears. - **Pick one** from **Add integration** (or **Edit**, once the panel lists some) and Insulin rewrites the description to name it. The description box reads *Updating the description…* until the rewrite is in. - **Remove a chip** and Insulin rewrites the description to take that integration out. If the rule depends on it, the description keeps it and the panel says why — for example *"Slack can't be removed here — it's where the rule sends its message. Edit the description to change that."* Email, CRM and marketplace-event rules all search these integrations for context before they draft. Nothing is saved until you click **Save**. ### Preview: run the rule without sending anything **Preview** sits between **Details** and **Save**, and is enabled exactly when **Save** is — it runs the rule *as you have just written it*, not the version last saved. It walks four steps, narrating each one with how long it took and what it produced: | Step | What happens | | ---- | ------------ | | **Interpret** | Turns your description into a structured rule — the same call **Save** makes. | | **Check** | Compares what the rule needs against what you have connected. A rule missing a piece stops here: it is not the rule you meant to test. | | **Sample** | Produces one sample event to run against. | | **Run** | Does the real matching and drafting, and shows the verdict plus each output, labelled with what a live event *would* have done. | **Nothing leaves the building.** A preview writes no approval row, sends no email, posts no Slack message, takes no CRM action, and does not move the trigger's stage cursor. Every output card is badged `Preview only - not sent`. The sample is read-only and says where it came from, so a generated example is never mistaken for a real record — a real record, a template, or written by AI. Two behaviours worth knowing: - **Hide only collapses the panel.** Re-showing it does not re-run; use **Run again** for that. - **Editing the description dismisses the results**, because they belonged to the description they ran on. ### Starter hints on a new rule A brand-new, still-empty rule shows a hint block under the buttons, which disappears as soon as you type anything. The top strip spells out the shape of every rule — **Trigger → Integrations → Output**: | Step | What it means | |------|---------------| | **Trigger** | What makes the rule fire — a new email (Gmail or Outlook), a CRM stage change (Salesforce, HubSpot, Microsoft Dynamics 365), or a Fours marketplace event (a co-sell referral, an entitlement, an offer, or a billing event). | | **Integrations** | The AI can search all of your user-level integrations as context. | | **Output** | What the rule produces — e.g. an email draft, a CRM update, a Slack DM. | Below it, **Try an example** chips fill the description box with a ready-made prompt you can edit before saving: - **Customer question → reply draft** — a full email rule: the filter, the context to gather (Gong calls, offers in Fours), and drafting guidance. - **Marketplace mail → labels** — a label-only rule: two labels, no draft. - **Salesforce stage → AWS referral** - **Technical Validation → intro draft** - **Stalled 30 days → bump or Slack** - **Entitlement suspended → Slack** ### Details **Details** opens a read-only view of the structured rule your description produced: the **Trigger**, the **Filter** (or, for a CRM rule, the stage / amount / owner it matches), the rule's **Email template** when it has one, the **Generation** inclusions and exclusions, and the **Actions** it routes to. The integrations the rule may search are on the [Integrations panel](#choosing-integrations) instead. You can open the Trigger picker to browse what is supported, but nothing there is editable — to change a rule, change its description and save again. When your description includes text that must go out exactly as written — a booking link, a required legal sentence — saving records it as the rule's **Email template**, which Details shows under *Fixed text goes out word for word; the rest is written for each recipient*: the fixed blocks first, then the guidance for writing the rest. A rule saved before email templates existed has none until you change its description and save it again. **Details** is unavailable on a brand-new draft (nothing has been generated yet) and becomes available once the rule is saved. ### Actions Every rule routes its outcome to one or more action cards: | Action | What it does | |--------|--------------| | **Email reply** | Replies to the sender of the triggering email. Choose one of two modes: **Draft for review → Approvals queue** (the safe default) or **Send automatically**. | | **Slack** | DMs *you* on Slack when the rule fires, with a link back to the queue. Requires your own [Slack](/integrations/slack/) connection — the card tells you which Slack user will be messaged. | | **CRM action** | Only on a CRM-triggered rule — Salesforce, HubSpot and Dynamics 365 all support it. Carries a written instruction, which is required, and lands in **Approvals ▸ Pending** behind a **Run in chat** button. It combines freely with the other two. | The two **Email reply** modes are mutually exclusive — a rule drafts for review or sends automatically, never both. :::warning **Send automatically sends without human review — within strict limits.** A rule in this mode sends replies straight to recipients, and the card marks it *no human review*. You can optionally tick **Always send the same text** and provide a fixed reply that is sent verbatim on every matching email; leave it unticked and the AI writes a fresh reply per email in your writing style. Either way the rule has to meet the bar in [When an auto-send rule may send](#when-an-auto-send-rule-may-send), and Inbox enforces it: - **Save** refuses an auto-send rule whose description doesn't compile to one exact, narrowing condition: the editor says *Nothing was saved.* and gives the reason, and **Preview** stops with the same reason. Describe a specific sender, subject or body condition, or switch the rule to drafts. - An existing auto-send rule that doesn't meet the bar can't be switched back on until you rewrite it. Switching any rule **off** always works. - An older auto-send rule saved before this check never fires. Open a mail it should have answered and the **Rules (N of M fired)** list in the conversation view shows it as **Skipped**, with the reason. Use this mode deliberately. ::: ![Inbox Settings → Rules with a new rule open — the rule list on the left with its enable switches, and on the right the rule name field, the "Describe the rule in natural language" box, the Discard / Details / Save row, and the starter-hint block showing the Trigger → Integrations → Output strip above six example chips](images/24-inbox-rules.png) ## Triggers: reacting to a CRM event A rule does not have to start from an email. Under **Settings → Account → Triggers**, Inbox lists the CRM sources it can react to (marketplace events need no trigger row — see [Triggers: reacting to a marketplace event](#triggers-reacting-to-a-marketplace-event)): | Trigger | Fires when | |---------|------------| | **Salesforce** | An opportunity moves to a stage you describe. | | **HubSpot** | A deal moves to a stage you describe. | | **Microsoft Dynamics 365** | An opportunity moves to a stage you describe. Drafts, Slack notifications and **CRM actions** all work as they do for the other two. A rule written around **won** or **lost** does behave differently here — see the note below. | All three are live. Each row is driven by *your own* user-level connection to that CRM, so: 1. Connect the CRM first. A row you have not connected shows **Connect**, which takes you to **Settings → Integrations** — see [Salesforce](/integrations/salesforce/), [HubSpot](/integrations/hubspot/), or [Microsoft Dynamics 365](/integrations/microsoft-dynamics365/). 2. Click **Enable** on the row. The row then shows an **Enabled** badge. 3. Write a rule that describes the CRM event you care about, in **Settings → Rules**. Turning a trigger off with **Disable** keeps your rules: they stay saved and go dormant until you enable the trigger again. ## Triggers: reacting to a marketplace event Rules can also fire on events from your Fours marketplace data — the reason to run Inbox next to Fours rather than a generic AI email app. There is no row to enable under **Triggers**: describe the event in a rule and saving the rule subscribes to it. | Family | Fires on | |--------|----------| | **Co-sell referral changed** | A referral is accepted, approved, rejected, updated, pending acceptance, received inbound, assigned a cloud-provider team member, or has gone quiet (**stalled**) for a number of days you choose. A referral rule can also name the partner-side sales stage it should react to (for example *Technical Validation*). | | **Entitlement changed** | An entitlement is created, suspended, cancelled, reinstated, terminated, or ending soon. | | **Offer changed** | An offer is created, sent for acceptance, accepted, signed, expired, expiring soon, or cancelled. | | **Billing event** | An invoice is issued, a payment is charged, or a payment is refunded. | Every family can be narrowed to one cloud partner (AWS, Azure, GCP) and, where it applies, to an entity status or a name. A marketplace rule produces the same outputs as any other: a drafted email in **Approvals ▸ Pending** — for a referral, addressed to the cloud provider's team on the deal when Fours knows them — and, or, a Slack notification. Before it drafts the email, it searches the integrations the rule names for context about that account, as email and CRM rules do. Three of the starter chips on a new rule are marketplace rules: **Technical Validation → intro draft**, **Entitlement suspended → Slack**, and **Stalled 30 days → bump or Slack**. :::caution[Won and lost look the same on Dynamics 365] Describe a rule around a deal being **won** or **lost** and it matches that outcome on every connected CRM — `Closed Won` / `Closed Lost` on Salesforce and HubSpot, and `Close` on Dynamics 365. Dynamics 365 reports a single `Close` stage for both outcomes, and the stage-change event does not carry which one it was. So on Dynamics a **won** rule fires on every closed opportunity — including the ones that were lost — and a **lost** rule does the same. Salesforce and HubSpot distinguish the two correctly. If that matters, scope the rule to Salesforce or HubSpot. There is no Dynamics-side workaround today — naming the `Close` stage directly does not help, because that is the one stage Dynamics reports for both outcomes. ::: ## Labels Labels are declared on rules. Write what to label in the rule's description — *"When an email is about an AWS Marketplace private offer, label it with 'Cloud partners' and 'Co-sell'"* — and every mail that rule matches gets those labels. A rule can label only (no draft, no Slack), or label alongside its other outputs; labels are available on email rules only. A rule can declare at most five labels, each label is at most 40 characters, and names Gmail reserves for its own system labels are refused when you save. On a Gmail mailbox whose connection carries the `gmail.modify` permission (see [Drafts in your Gmail Drafts folder](#drafts-in-your-gmail-drafts-folder)), labels sync to your mailbox as real Gmail labels. In Inbox they show as chips on each mail rather than as a menu entry. Deleting or disabling the rule stops new mail from being labelled; mail already labelled keeps its label. ## AI Model Inbox needs one working AI model to interpret your rules and draft replies. The **AI model** section of **Settings → Account** lists five model providers — Claude Code, Codex, Anthropic, OpenAI, and Gemini — and shows **Connected** or a **Connect** link for each. A credential whose sign-in has lapsed is treated as not connected and shows **Connect** too — re-authorizing and connecting for the first time are the same flow on the Integrations page. Inbox can also use other AI providers you have connected yourself — including the open-source aggregators, Cloudflare Workers AI, and DigitalOcean GradientAI — even though this section does not list them. :::warning With no provider of your own connected, Inbox runs on Fours' hosted models and the card says so; connect a provider below to use it instead. If no model is available at all — no provider and hosted models not allowed for your organization — rules can't be interpreted and no draft is produced; Inbox simply looks quiet. The rule editor's **Preview** names this as the first thing to fix. ::: Connecting and disconnecting model credentials happens on the Integrations page; this card only reports the state and links you there. **Inbox falls back to another model rather than failing.** The work Inbox does outside a chat — classification, tagging, drafting a reply or a CRM action, synthesizing a rule, summarizing a thread, building your writing-style profile — now walks the same chain of candidate models the chat agent uses. If your first provider is unavailable or has hit a usage limit, the next connected provider takes over, and Fours' hosted models are the last resort. A single provider running out of quota no longer silently stops every one of those jobs. ## Writing Style Insulin learns your writing style from your recent sent mail so AI drafts sound like you. It is shown under **Settings → Account → Writing style**, is used **only** for draft generation, and never leaves your tenant. The card reports one of four states: | State | What it means | |-------|---------------| | **Built from N recent emails** | Ready. A summary below shows your greeting, sign-off, register, and common openers and closers. | | **Building…** | A build is in progress. It can take a few minutes. | | **Build failed** | The build failed, with the reason. | | **No voice profile yet** | Nothing has been built. | A build starts automatically when you enable Inbox, and **Re-generate** rebuilds it from your latest sent mail at any time — including out of a stuck or failed state. **Your edits teach it, too.** When you send a reply the AI drafted, Insulin compares what it wrote with what you actually sent. An edit that changes the style — tone, length, a greeting or sign-off, phrasing — yields at most one writing preference; an edit that only corrects facts such as names, dates, amounts or links teaches nothing, and a reply you sent essentially as drafted reinforces the profile you already have. Once ten preferences have collected, they are folded into your writing style. Replies the AI didn't draft — pinned canned text, or mail you wrote from scratch — are not learned from. Learning runs on your own Insulin model, reads only your own mail, and never holds up or fails a send. ## Knowledge Bases Attach knowledge bases to Inbox and it will consult them while drafting replies — useful for product documentation, canned answers, or a support playbook, so drafts draw on your actual material instead of improvising. Open **Settings → Account** and find the **Knowledge bases** section. Tick a knowledge base to use it when drafting; untick it to stop. The list shows every knowledge base you can reach, including organization ones shared with you. Leave everything unticked and drafts are written exactly as before, with no knowledge base context. :::info Knowledge bases attach to your Inbox **account-wide, not per rule.** One selection applies to every draft Inbox writes for you. ::: Inbox only ever **reads** a knowledge base — there is no Read/Edit choice here, and Inbox never adds to or changes one. (The built-in Insulin assistant has its own separate selection, which *can* be granted edit access — see [Knowledge Bases](/insulin/knowledge-base/#choosing-which-knowledge-bases-insulin-uses).) The attached knowledge bases are searched only for drafts on their way to **Approvals ▸ Pending**. A reply that is sent automatically never consults them — no outside context goes into an automatic reply (see [When an auto-send rule may send](#when-an-auto-send-rule-may-send)) — and a rule with pinned canned text involves no model at all. | Limit | Value | |-------|-------| | Knowledge bases you can attach | Up to 100 | | Knowledge bases searched per draft | The first 3 you still have access to, in the order you saved them | | Passages taken from each knowledge base | Up to 4 | :::info Knowledge base lookup is best-effort. If a search fails or runs long, Inbox still writes the draft — just without the extra context. Access is re-checked every time, so a knowledge base you lose access to is silently skipped. ::: ![Inbox Settings → Account scrolled to Knowledge bases — the Writing style card above a checkbox per knowledge base, showing that knowledge bases attach to the account rather than to an individual rule](images/23-inbox-knowledge-bases.png) ## Use Cases - **Sort your mail your way** — Write rules that label the mail you actually get, and browse each label under **Mails**. - **Faster replies in your voice** — Approve AI-drafted replies that already sound like you instead of writing from scratch. - **Follow up when a deal moves** — Enable the Salesforce, HubSpot, or Dynamics 365 trigger and write a rule that drafts the follow-up email the moment an opportunity changes stage. - **Keep the CRM current** — Add a **CRM action** to that rule, then click **Run in chat** to watch the agent apply it. - **Hands-off acknowledgements** — Author a rule that sends automatically with a canned reply, to acknowledge a specific class of email without review. - **Ask about your inbox** — Use the chat rail to triage out loud: *"which of these need a reply today?"* --- Source: https://doc.fours.com/insulin/slack-bot/ # Slack Bot Ask Insulin from Slack: direct-message the bot, or `@mention` it in a channel. --- ## What You Get The Fours bot is not a separate assistant. It is the **same Insulin agent** you use in the console, reached from Slack instead of a browser — your connected integrations, your knowledge bases, your memory, your role. The surface changes; what you can do does not. That has a practical consequence worth knowing up front: **everything is configured in the console, and Slack inherits it.** Connect a tool there and the bot can use it here. Connect nothing and the bot can still talk, but it has nothing to reach into. There is no separate setup on the Slack side, and nothing to configure per channel. Use it when the question comes up where the work is happening: a deal in a sales channel, an entitlement question in support, a revenue figure during a standup. ## Before You Start Two things have to be in place. 1. **An org admin connects Slack.** In the Fours console, go to **Settings ▸ Integrations** and connect Slack for your organization. This installs the Fours app into your Slack workspace. Any member can see the organization's integrations, but only an org admin can connect one. 2. **Your Slack email matches your Fours account.** The bot identifies you by the email on your Slack profile, finds the matching Fours user, and checks that you are a member of the organization this workspace is connected to. If your Slack profile has no email, or uses a different address than your Fours account, the bot will tell you so rather than guess. Nothing else is needed to *talk* to the bot — no API key, no per-person install. What it can *do* for you depends on the third step. 3. **Connect the tools you want it to use.** The bot reaches only what you have connected in the console, under **Settings ▸ Integrations**: - **Your Fours resources** — offers, products, entitlements, buyers, revenue, co-sell records — come through the **Fours MCP server**, under **Settings ▸ Integrations ▸ Custom MCP Servers**. This one is required for any question or action about Fours data. Without it the bot works but has nothing to read, and it will tell you the connection is missing rather than claim the data does not exist. - **Your own tools** — Gmail, Google Calendar, Google Drive, Gong, Salesforce and the rest — are personal connections, available to your agents alone. Connect them once in the console and they work in Slack too. Each integration's own page covers both halves: how to connect it to your account, and what the agent can then do with it. **[Gong](/integrations/gong/)** is a worked example — [Create User Integration](/integrations/gong/#create-user-integration) is four steps through an OAuth redirect, and [Fours AI Tools](/integrations/gong/#fours-ai-tools) lists what that buys you, from reading call transcripts to finding a company's calls by the CRM account linked to them. Once it is connected, "what did we discuss on the last call with this buyer?" works in Slack exactly as it does in the console. When you connect the Fours MCP server you choose how far it reaches, and **the default is read-only**: | Access | What the bot can do | | --- | --- | | **Read** (default) | Look things up and report them. It cannot change anything. | | **Read & write** | Also create and update records — an offer, a referral. | | **Read, write & delete** | Also delete them. | Pick the level you actually want. If you ask the bot to create something and it tells you it cannot, a read-only connection is the usual reason. The level caps which tools it is offered; your own Fours permissions still apply on every call, so it can never do something through Slack that you could not do in the console. :::info **Connections are per person, not per channel.** Two people mentioning the bot in the same Slack channel each get their own: yours reaches your calendar and your Fours organization, theirs reaches theirs. Nothing you connect becomes available to a colleague because you both use the bot in one place. **Organization-level integrations are never available here.** The bot is the Insulin agent, and that agent is user-level by design: it runs on your own connections and never holds the organization's. Those are reached by org-level agents instead. This holds even if you are an org admin — it is a boundary, not a permission you are missing. So when the bot says it lacks an integration, it is describing *your* connections, and connecting that tool to your own account is the fix. ::: ## Asking in a Direct Message Open a direct message with the Fours app and type as you would in the console. No mention is needed — every message is a question for the bot. A direct message is a continuing conversation: the bot remembers what you asked earlier in it, so you can follow up with "and for Azure?" without repeating yourself. ## Asking in a Channel In a channel, the bot answers when you **`@mention`** it and never otherwise. It does not read along, and it does not reply to messages between colleagues — being in a channel is not the same as being addressed. Its reply mentions you, so you can tell which question it belongs to when several people are asking at once. In a **private** channel the bot has to be invited before it can see a mention at all — `/invite @Fours` once, and it works there like any other channel. **Each mention is its own conversation.** Mentioning the bot again at the top level of a channel starts a fresh exchange rather than continuing the last one. To carry on, reply **in the thread** under its answer — there the bot keeps the context of that thread, including the messages your colleagues wrote in it. :::info **A channel conversation is read-only.** Anyone in a channel can write anything, so a mention there gets a bot that can read and report but cannot change, create or send anything on your behalf. Ask in a direct message when you want it to act. ::: ## What You Can Ask Anything you would ask in the console. In practice the questions that suit Slack are the ones that come up mid-conversation, where opening the console would break the thread: - **Look something up** — a buyer's entitlements, an offer's status, which products a customer is on, how a co-sell referral is progressing. - **Roll something up** — new entitlements this week, offers awaiting acceptance, pipeline by partner. Ask for the count rather than the list when that is what you want. - **Work out why something failed** — give it the offer or referral and ask what went wrong; it reads the record and reports what it finds rather than guessing. - **Pull a brief together** — if you have connected [Gong](/integrations/gong/) and Salesforce, ask for the picture before a call and it combines what each one knows. - **Change something** — create or update an offer or referral, if you granted the connection write access. - **Draft something** — an outreach email, a summary of the thread you were just added to. What it can reach is what *you* connected, so two people asking the same question in the same channel can get different answers. That is the model working, not a fault. ## While It Works The bot posts a short status as it goes — "Gathering information", or the name of the tool it is using — then replaces it with the answer. A long question can take a minute or more; the status is how you know it is still working. If an answer is a large table, you get a CSV file instead of a wall of text, with the links preserved so you can open each record. ## Approving an Action Before the bot **sends a message on your behalf**, it stops and asks. Rather than sending and telling you afterwards, it posts a card naming the action and its exact target — the message, and the channel or person it would go to — with **Allow** and **Deny**. - Only the person who asked can decide. A card in a channel is visible to everyone, but a click from anyone else is refused. - Nothing happens until you choose. **Deny** and the action is dropped. - You have **three minutes**. After that the card expires, the action is abandoned, and the bot says so — ask again if you still want it. Read the target before you allow it. The card spells out the destination precisely so a near-miss — the right message to the wrong channel — is visible before it happens rather than after. :::info **Changes to your own records are not gated this way.** Ask the bot to update an offer and it updates it, the same as a teammate would on your instruction. What bounds that is the access level you gave the Fours MCP connection — read-only means it cannot change anything at all, whatever it is asked. Decide there, not here. ::: ## Answering a Question When the bot needs a choice from you — which organization to create an offer under, which of several matching records you meant — it posts the question with a button for each option. Pick one and it carries on from there. As with approvals, only the person who asked can answer. ## Handing Work to a Job Because this is the same agent, you can also ask it to automate something — there is no form to fill in, in Slack or in the console. Tell it what you want to happen and when: > every weekday at 9am, summarise new AWS entitlements It creates the [job](/insulin/jobs/) for you, choosing the trigger that matches what you asked — a recurring schedule, an incoming event, or a single run you start yourself. A job you create this way is yours. It runs with your access and your connections, and it is private to you: only you can see, run, edit or delete it, org admins included. Manage it and read its run history in the **Jobs** app in the console, where every run leaves a record you can open. ## Troubleshooting | What the bot says | What it means | | --- | --- | | This Slack workspace isn't connected to a Fours organization | The Slack integration was disconnected in Fours, but the app is still in your workspace. Ask an org admin to reconnect it under **Settings ▸ Integrations**. | | I couldn't read your Slack email | Your Slack profile has no email, or the workspace admin has not granted the Fours app permission to read profiles. | | I couldn't find a Fours account matching your Slack email | No Fours user has that address. Sign up, or ask an admin to invite the address your Slack profile uses. | | Your Fours account isn't a member of … | You have a Fours account, but not in the organization this workspace is connected to. The message names that organization; ask one of its admins to add you. | | It mentions no Fours data connection | The per-person Fours MCP connection is missing, so it can neither read nor change Fours records — see **Before You Start** above. | | It says it does not have an integration | That tool is not connected under **your** account. Connect it in the console under **Settings ▸ Integrations**; an organization-level connection does not count. | | It says it cannot create or change something | The Fours MCP connection is read-only — the default. Reconnect it with **Read & write** under **Settings ▸ Integrations ▸ Custom MCP Servers**. | | A teammate gets an answer you do not | Each of you runs on your own connections and your own Fours access. Compare what you have connected before assuming the data is missing. | **The bot does not answer at all.** Check that you mentioned it rather than typing its name as plain text, and that it is in the channel — a private channel needs `/invite @Fours` first. In a direct message, check that the app appears in your Slack sidebar. --- Source: https://doc.fours.com/insulin/billing/overview/ # How Billing Works Insulin is billed on what you consume — model tokens, sandbox runtime, and stored files. There is no seat count and no subscription tier. Find it all under **Settings → Billing**, in the Fours console or in the **Settings** app on the [Insulin desktop](/insulin/getting-started/). Every member of a seller, reseller, or partner organization can open the page; there is no admin-only view. ![Settings → Billing — the credit balance, month-to-date spend, auto-refill and monthly limit cards, above the payment method, spending limit, automatic top-up and credit sections](images/billing-overview.png) --- ## The two billing models | | Pay as you go | Monthly billing | |---|---|---| | When you pay | Before you use it | After, on an invoice | | Payment method | Optional until you want to add credit | Required | | Running out | AI requests pause at a zero balance | No automatic cut-off | | Suits | Most accounts | Committed or contracted usage | Every account starts on **pay as you go**. Your current model is shown as a badge beside the **Billing** heading. Switching between them is arranged with Fours and takes effect **at the start of the next month**, not immediately — a mid-month switch would split one month's usage across two sets of rules and produce an invoice nobody could explain. Unused purchased credit carries across the change. ## A month, start to finish ```d2 direction: right classes: { step: { width: 210; style.border-radius: 8 } note: { width: 210; style.border-radius: 8; style.stroke-dash: 3 } } grant: "1st of the month\nFree credit granted" { class: step } spend: "Through the month\nUsage metered, priced,\nand taken off the balance" { class: step } close: "1st of the next month\nPeriod closes\nand the figure is final" { class: step } expire: "Unused free credit\nexpires — it does not\ncarry over" { class: note } invoice: "Invoice issued, once\ninvoicing is enabled" { class: note } grant -> spend -> close close -> expire close -> invoice ``` ### What the invoice does depends on your billing model On **pay as you go** the usage was already paid for as it happened — every request came off a credit balance you had already funded. The invoice for the period is therefore a **statement**, and collects nothing. The one exception is a balance that ended the month below zero: storage and an already-running sandbox keep accruing after AI requests stop, and that overshoot was never covered by credit, so it is collected. On **monthly billing** nothing was collected as you went, so the invoice **is** the bill: it carries the period's metered total, any credit you hold is applied against it on the document, and the balance is returned to zero so the next period starts clean. Two things can stop an invoice being issued for a closed period. Invoicing is enabled per account by Fours, and nothing is issued before it is. And an amount to collect that is below the payment provider's **$0.50** minimum is carried into a later period rather than charged — the period simply stays open. In both cases the usage is still metered, and on pay as you go it has still come off your balance. ## What is charged Six resources are metered. [What is metered](/insulin/billing/metering/) covers how each is measured; this is the short version. | Charged | How it is measured | |---|---| | AI input tokens | Everything sent to the model, including cached context | | AI output tokens | Everything the model produces, including reasoning tokens | | Sandbox processor | While the sandbox is running | | Sandbox memory | While the sandbox is running | | Sandbox storage | While the sandbox **exists**, including while it is stopped | | Object storage | The highest volume held on any single day of the month | Two of these surprise people, so they are worth stating plainly. **A stopped sandbox still costs storage.** Stopping releases processor and memory, but the volume is still reserved for you. Delete the sandbox to stop the charge. **Object storage bills the month's peak, not the month's end.** If you hold 500 GB for one day and delete it, that month is billed for 500 GB. The capacity was reserved on the day you used it, and deleting afterwards does not give it back retroactively. ## Credit Credit offsets consumption. It appears in the **Credit** table at the bottom of the page, with the amount granted, what is left of it, and when it expires. | Kind | Shown as | Valid for | |---|---|---| | The monthly free allowance | **Monthly free credit** | The month it was issued | | Credit added by a top-up or purchase | **Purchased credit** | Three years | | Credit granted by Fours | **Fours credit** | As stated when it was granted | | A correction to a period | **Adjustment** | That period | Every organization is granted **$100 of free credit** on the 1st of each month. Some accounts have a different recurring amount arranged with Fours; the Credit table always shows the real figure for your organization. **Credit is spent soonest-expiry first.** So the monthly free credit is used before credit you paid for, and paid credit is not wasted while free credit sits unused. This is also the answer to "which credit paid for this?" — the one that was closest to expiring at the time. Unused free credit does **not** roll over. It expires at the end of the month it was issued in. ## Estimated versus final The **Used this month** card is labelled **Estimated — final on the invoice** while the month is open, and **Final** once the period has closed. That is not a hedge. A mid-month figure is a running total that will still move — storage is billed on the month's peak, which is not known until the month ends, and consumption from the last few minutes may not be aggregated yet. The final figure is the one that is charged. The **Credit balance** beside it behaves differently: it is live, and reflects consumption within about a minute. :::info Selecting a past month shows that month's usage and its settled total. The credit balance shown above it is always your balance **now**, not the balance at the end of the month you are looking at. ::: ## What is not billed - **Fours' own use of AI.** Platform features that call a model internally — summarization, search indexing, field mapping, reranking — are not billed to you. - **Anything outside Insulin.** Only consumption in the AI service reaches the billing records. ## Where to next - [What is metered](/insulin/billing/metering/) — the units, the pricing rules, and BYOK. - [Reading your usage](/insulin/billing/usage/) — attributing spend to people, apps and models. - [Payment, limits, and top-ups](/insulin/billing/spend-controls/) — the controls you own. - [When AI pauses](/insulin/billing/when-ai-pauses/) — what stops, what does not, and why. --- Source: https://doc.fours.com/insulin/billing/metering/ # What Is Metered Insulin measures six resources. Each is recorded as it is consumed, priced against the rate in effect for that month, and taken off your credit balance. --- ## The six metered resources These are the rows you see under **Resource** in the usage breakdown, with the unit each quantity is counted in. | Resource | Unit | Measured | |---|---|---| | **AI input tokens** | tokens | Everything sent to the model on each request | | **AI output tokens** | tokens | Everything the model produces | | **Sandbox processor** | processor-seconds | While a sandbox is running | | **Sandbox memory** | GB-seconds | While a sandbox is running | | **Sandbox storage** | GB-seconds | For as long as the sandbox exists, running or stopped | | **Object storage** | MiB-months | Files held in your organization's storage | ### Tokens Input and output are counted separately because every provider charges differently for each direction, so each direction needs its own rate. **Cached context is counted in full.** A long conversation resends earlier turns on every request, and providers charge for those tokens even when they serve them from cache. They are recorded as input tokens, and today they are priced at the same rate as fresh input. **Reasoning tokens count as output.** Models that think before answering bill that thinking at the output rate, and Fours records it the same way. **Failed and cancelled requests are still billed.** A generation that fails partway has already been run, and the provider charges Fours for it whether or not the answer reached you. Whatever token count the provider reports for the failed call is what is metered. **AI a Custom App runs is billed like any other AI.** When a [Custom App](/insulin/custom-apps/) calls a model at runtime, those tokens are metered and priced the same way a chat turn's are. This used to run only on your own keys and record $0; it can now run on a Fours-hosted model, which Fours pays the vendor for — so it is charged rather than recorded for free. If your organization has no model such a call can run on, the call is refused with *"No usable model provider configured"* rather than silently returning nothing. ### What the Fours-hosted models cost Fours The Fours-hosted pool runs on one supplier. These are that supplier's published prices per million tokens, read from Fours' own rate table — the rate you are charged is these plus the margin described under [How prices are set](#how-prices-are-set). | Fours-hosted model | Input | Output | |---|---|---| | DeepSeek V4 Pro | $1.30 | $2.60 | | DeepSeek V4 Flash | $0.09 | $0.18 | | GLM 5.3 Flash | $0.15 | $0.50 | | Gemma 4 31B | $0.20 | $0.40 | DeepSeek V4 Pro is the pool's quality tier; the other three are its light tier. Which of them a turn may use is not only a question of price — see [the tier step-down](/insulin/billing/spend-controls/#the-fours-hosted-tier-step-down). ### Sandboxes A sandbox bills three things independently, because the sandbox provider bills Fours for three things independently. - **Processor and memory** accrue while the sandbox is *running*. Stopping it ends both. - **Storage** accrues for as long as the sandbox *exists*. Stopping does not release the volume — it is still reserved for you, and Fours is still charged for it. **Deleting the sandbox is what stops the charge.** Accrual is measured in windows rather than in one lump at the end, so a sandbox left running for weeks shows up in the usage breakdown as it goes rather than arriving as a surprise. ### Object storage Object storage is not consumed, it is *held* — so it is measured as a gauge rather than counted. Once a day, Fours records how much your organization is holding, across shared organization storage and each member's own storage together. **The month is billed on its highest daily reading.** Not the average, and not the figure at month end. If you hold 500 GB for a single day and delete it, that month bills 500 GB: the capacity was reserved on the day you used it, and the supplier charged for it then. ## From consumption to a number on your bill ```d2 direction: right classes: { box: { width: 215; style.border-radius: 8 } } use: "You use Insulin\nChat, agents, jobs,\nsandboxes, files" { class: box } meter: "Measured\nQuantity, plus who, which\napp, model and provider" { class: box } price: "Priced\nAgainst the rate in\neffect for that month" { class: box } ledger: "Balance\nTaken off your credit,\nsoonest-expiry first" { class: box } rollup: "Usage breakdown\nRe-aggregated for\nthe console" { class: box } gate: "Spend check\nDecides whether the\nnext request may run" { class: box } use -> meter -> price -> ledger ledger -> gate: "within a minute" ledger -> rollup: "every couple of hours" ``` The two arrows out of the balance are why the page can look inconsistent for a short while: the **Credit balance** moves within about a minute of a request, while the **usage breakdown** is re-aggregated every couple of hours. A balance that has dropped against a table that has not caught up is the normal, expected state — not a missing charge. See [Reading your usage](/insulin/billing/usage/). ## How prices are set **Fours prices everything; the payment provider only collects.** Stripe holds no rate card and performs no pricing — it receives an already-priced invoice. That is what makes the invoiced total equal the metered total. - **Rates are effective-dated and immutable.** A price change applies to the month it takes effect in and to later months. It never reaches backwards: re-pricing a closed period reproduces the original amount. - **Rates are refreshed monthly**, ahead of the month they apply to, from the supplier's published prices. - **An automatic price rise is capped.** A refreshed rate more than 25% above the previous one is rejected and the previous price is kept, so a misread supplier page cannot reach an invoice. Price *cuts* are accepted at any size — providers cut sharply and often, and refusing a real cut would keep overcharging you. - **A model with no published rate is still billed, at a documented fallback.** The fallback supplier cost is $5.00 per million input tokens and $10.00 per million output tokens; with the margin below applied, the charged rate is **$7.50 per million input tokens** and **$15.00 per million output tokens**. Newly released models are the usual case, and consumption is never silently dropped for want of a price. Fours' price is the supplier's cost plus a margin: **50%** on model calls Fours supplies the key for, and **30%** on sandbox and storage. Prices are in **US dollars** and exclude tax. ### Using your own provider keys (BYOK) If you connect your own model provider key, that provider bills you directly for the tokens, under your own contract. Fours' charge is then a **flat fee per unit** rather than a percentage — a percentage of a cost Fours does not incur would be nothing, while the platform still routes and secures every request and meters the token usage the provider reports. Two consequences worth knowing: - BYOK usage still appears in your usage breakdown, attributed to the provider whose key was used, whenever the provider reports how many tokens the request used. For streamed replies, Fours does not currently ask Cloudflare Workers AI, DigitalOcean GradientAI, or Together AI for that count, so a reply streamed from one of them may be missing from the breakdown. - A **zero balance still pauses BYOK requests**, because the per-unit fee is still owed. See [When AI pauses](/insulin/billing/when-ai-pauses/). ## What is never billed - **Fours' own AI.** Platform features that call a model internally — summarization, search indexing, embeddings, reranking, field mapping — are Fours' cost, not yours. They are metered for operational monitoring and never reach billing. - **Anything outside Insulin.** Only consumption in the AI service is billed. - **Reading what you already have.** Opening, listing or searching your stored files, and starting, stopping or connecting to an existing sandbox, are never refused for billing reasons and are not separately charged. - **Database storage.** Not metered. ## How long the detail is kept | Record | Kept for | |---|---| | Individual consumption records | 90 days | | The attributed usage breakdown you see in the console | 13 months | | Period totals | Indefinitely | After 13 months the breakdown is *collapsed* rather than deleted: the attribution — which user, which app, which model — is dropped, and a daily total per resource remains. A history that ended abruptly would read as data loss. The period selector offers the last **12 months**, which is inside the window where the full attributed breakdown still exists. --- Source: https://doc.fours.com/insulin/billing/usage/ # Reading Your Usage The **Usage** panel sits below the summary on **Settings → Billing**. It answers one question — *what is costing this much* — by re-pivoting the same period across the attributes Fours records as consumption happens. ![The Usage panel — group-by tabs, filters, the daily spend chart, and the period grouped by resource with quantity, cost and share columns](images/billing-usage-by-resource.png) --- ## Choose the month The period selector at the top of the page drives **both** panels, so the summary and the usage table always describe the same month. It offers the last **12 months**, newest first, with the current month marked *(current)*. Selecting a closed month shows that month's settled figures. The credit balance above is always your balance *now*. ## Group the period The tab strip re-pivots the same consumption. Every pivot totals the same amount. | Group by | Answers | |---|---| | **Resource** | What kind of thing did the money go on — tokens, sandbox, storage | | **User** | Which member of the organization caused it | | **App** | Which Insulin app it ran under | | **Model** | Which model was used | | **Provider** | Which provider served it | Each row shows a **quantity**, the **cost**, and the row's **share** of the period. The unit is named only in the **Resource** grouping: every other grouping mixes resources measured in different units — tokens with processor-seconds — so a single unit label would be wrong. ### Rows with nothing to attribute Some consumption genuinely has no value for the dimension you picked: a scheduled job has no user, a direct API call has no app, sandbox storage has no model. Those rows are **named rather than dropped** — | Grouping | The unattributed row reads | |---|---| | User | *No user — scheduled and system runs* | | App | *No app* | | Model | *No model — sandbox and storage* | | Provider | *No provider — sandbox and storage* | ![The same period grouped by user, with three named members and an italic 'No user — scheduled and system runs' row carrying the remainder](images/billing-usage-by-user.png) This is why the pivots reconcile. If unattributed consumption were left out, the by-user view would quietly total less than the by-resource view, and neither would match your bill. ## Narrow it with filters Four multi-select filters — **users**, **apps**, **models**, **providers** — sit under the tabs. Grouping and filtering answer different questions: grouping is *what did we spend it on*, filtering is *what did this team spend it on*. A filter's choices come from the grouping currently shown, so **the filter matching the active tab is the one with values to pick**. To narrow by user, switch to the **User** grouping first and the Users filter fills with the people who actually used AI this period; the selection then stays applied as you switch to another grouping. This is also why no filter ever offers someone who never used AI — the list is built from the period's own results, not from your member list. With any filter applied the panel says so, because **a filtered total is a subset of the period, not the whole bill**. **Clear filters** returns to the full period. ## The daily spend chart One bar per day of the period, with the peak day highlighted and labelled above the chart. Days with no spend render as an empty slot rather than being closed up — a chart that bridged a quiet weekend would draw a slope across spending nobody can account for. ## Why the table can look emptier than your balance The usage breakdown is re-aggregated **every couple of hours**. The credit balance above it comes straight from the ledger and moves within about a minute of a request. So this sequence is normal: 1. You run something expensive. 2. The **Credit balance** drops immediately. 3. The **Usage** table still shows the period without it. The panel says as much above the table. If the two disagree, **the balance is the current one** — the table is catching up, and nothing has been lost or double-counted. An empty table therefore means *nothing has been aggregated for this period yet*, which is not the same as *you have used nothing*. ## What this panel does not do There is no CSV export and no per-request drill-down. The finest grain available here is a grouped row for the period. If you need the underlying detail — to reconcile a specific job or a specific day — contact [support@suger.io](mailto:support@suger.io) while the consumption records are still inside their 90-day retention window. --- Source: https://doc.fours.com/insulin/billing/spend-controls/ # Payment, Limits, and Top-Ups Three controls on **Settings → Billing** belong to you: the payment method on file, a monthly spending limit, and automatic top-up. Everything else about the account — the billing model, the debt limit, and suspension — is set by Fours under an approval trail. --- ## Add a payment method You do **not** need one to use Insulin. The $100 monthly free credit is spendable without a card, and most accounts never add one. Add one when you want automatic top-up, or when you are moving to monthly billing. 1. Open **Settings → Billing**. 2. Under **Payment method**, select **Add payment method** (or **Add another** if one is already saved). 3. You are taken to **Stripe's hosted checkout page** to enter the details, then returned to the same billing page. Cards and US bank accounts are both accepted. Saved methods are listed by brand and last four digits — *Visa ending 4242*, *Bank account ending 6789*. :::info **No card details are entered in the Fours console.** The form is Stripe's, on Stripe's page. Fours stores a reference to the method, never the number. ::: If the payment provider is briefly unavailable the panel says so and states plainly that your credit balance and AI usage are unaffected — it is a problem on Fours' side, not something to fix in your own settings. ## Set a monthly spending limit A ceiling on what the organization may spend in a calendar month, whichever billing model it is on. 1. Under **Monthly spending limit**, enter an amount in US dollars. 2. Select **Save limit**. To remove it, select **Remove**, or clear the field and save. An empty field means *no limit*. | Rule | Detail | |---|---| | Range | 0 to $100,000 per month | | When it applies | Compared against the month's spend so far, on both billing models | | What it does | Pauses AI requests for the rest of the month | | What it also does | **Stops automatic top-up** — you asked not to spend more | | Resets | At the start of the next month | **Reaching your limit is not the same as running out of credit,** and the fix is different: your balance is untouched, so adding credit will not resume service. Raise or remove the limit instead. See [When AI pauses](/insulin/billing/when-ai-pauses/). A limit set below what you have already spent this month applies straight away, though it can take up to a minute for in-flight requests to start being refused. ## Turn on automatic top-up Automatic top-up charges your saved payment method once the balance is at or below a trigger you choose, so a long-running job is not interrupted by a balance nobody was watching. 1. Save a payment method first — the switch is disabled without one, because there would be nothing to charge. 2. Turn on **Automatic top-up**. 3. Set **When the balance is below** (the trigger) and **Top up by** (the amount). 4. Select **Save top-up settings**. | Rule | Detail | |---|---| | Requires | A saved payment method | | Trigger range | 0 to $100,000 | | Top-up range | Greater than 0, up to $100,000 | | Hard rule | **The top-up must be larger than the trigger** | | Checked | Every five minutes | | Overridden by | Your monthly spending limit | **Why the top-up must exceed the trigger.** A top-up that lands back on its own trigger fires again immediately, and again after that. It is the only setting on this page that can charge real money repeatedly rather than once, so the console refuses to save it. Credit added this way is **Purchased credit** and stays valid for three years — it is not lost at the end of the month. :::warning **A payment method removed later silently disarms automatic top-up.** If the setting is on but no method is saved, the panel says so and nothing will be charged. Add a method to restore it. ::: ### How the limit and the top-up interact Your monthly spending limit wins. Once the month's spend reaches it, no top-up is charged for the rest of the month, whatever the balance does — charging you for credit you asked not to spend would defeat the point of setting a limit. The panel states this above the Save button whenever a limit is set. This is the order the two controls are evaluated in, and it answers the two questions people arrive with: *why didn't my top-up fire?* and *why didn't adding credit bring the service back?* ```d2 direction: down classes: { q: { shape: diamond; width: 260 } stop: { width: 250; style.border-radius: 8 } ok: { width: 250; style.border-radius: 8 } } trigger: "Balance falls to\nyour top-up trigger" { style.border-radius: 8 } limit: "Month's spend already\nat your monthly limit?" { class: q } method: "Payment method\nsaved?" { class: q } blocked: "No top-up is charged\nfor the rest of the month.\nRaise the limit to resume." { class: stop } disarmed: "Top-up is disarmed.\nAdd a payment method." { class: stop } charged: "Top-up is charged\nand the balance rises" { class: ok } trigger -> limit limit -> blocked: yes limit -> method: no method -> disarmed: no method -> charged: yes blocked -> note: "" { style.opacity: 0 } note: |md Adding credit does **not** clear the monthly limit — the limit is a cap on spend, not on balance. | { style.border-radius: 8; width: 300 } ``` So a paused service resumes only once the blocking condition itself is cleared: raise or remove the **monthly spending limit** if that is what stopped it, and add **credit** if the balance is what stopped it. Adding credit while the limit is reached changes nothing until the next month or until you raise the limit. [When AI pauses](/insulin/billing/when-ai-pauses/) walks the full set of pause conditions. ## What you cannot change here | Setting | Who sets it | |---|---| | Billing model (pay as you go / monthly) | Fours, effective the following month | | Debt limit — how far below zero the account may go | Fours | | Suspension | Fours | | The monthly free credit amount | Fours | | The spend point at which Fours-hosted models step down a tier | Fours | These sit behind an approval trail on Fours' side, recorded with who changed them, when, and why. Contact [support@suger.io](mailto:support@suger.io) to request a change. ### The Fours-hosted tier step-down The last row is worth stating plainly, because nothing on screen announces it. The Fours-hosted model pool has two tiers: a **Tier 1** quality model and several lighter **Tier 2** models. Once your organization's spend **on Fours' own key** passes about **$300** in a billing period, Tier 1 stops being offered for the rest of that period and the pool serves Tier 2. | | Detail | |---|---| | What is counted | Only spend on Fours' key — your own [BYOK](/insulin/billing/metering/#using-your-own-provider-keys-byok) usage is not counted toward it | | Over what window | Your billing period, not a calendar month | | What changes | Tier 1 is withheld; Tier 2 stays available | | What does not change | Nothing is paused, refused, or refunded | | Resets | At the start of the next period | **It is not one of the [reasons AI pauses](/insulin/billing/when-ai-pauses/).** Those are refusals, and each raises a banner telling you which one applied. This is not a refusal: no banner appears, no request fails, and no conversation stops — the pool simply has fewer models in it, and answers may read as less capable. **Your own models are unaffected.** A connected provider's models are always preferred over the hosted pool, so an organization running on its own keys never meets this at all. If you want Tier 1 quality past that point, connect your own provider — see [how a turn resolves to a model](/insulin/agents/#how-a-turn-resolves-to-a-model). ## If a payment fails Stripe retries a failed payment on its own schedule, up to four attempts, before the cycle is treated as exhausted. Nothing happens to your account during the retries — the most common cause is a temporary hold or a card that gets replaced within a few days. Once the retries are exhausted: | Billing model | What happens | |---|---| | Pay as you go | The organization is suspended and notified. Update the payment method, then contact Fours to lift the suspension — it is not cleared automatically when a payment succeeds. | | Monthly billing | Nobody is cut off automatically. You are notified, and Fours' team follows up about the outstanding balance. | Stored files and running sandboxes are unaffected either way. --- Source: https://doc.fours.com/insulin/billing/when-ai-pauses/ # When AI Pauses When Insulin refuses a request for a billing reason, it says which of four reasons applies, because each has a different fix. A generic "billing problem" would send everyone to support. The reason appears as a banner at the top of **Settings → Billing**, and in the conversation itself if you were chatting when it happened. ![The billing banner reading "AI features are paused — your credit has run out", with the line "Add credit to resume. Stored files and running sandboxes are unaffected."](images/billing-paused-banner.png) --- ## The four reasons | Banner | Why | How it resolves | |---|---|---| | **This organization is suspended** | An administrative hold placed by Fours | Contact [support@suger.io](mailto:support@suger.io) | | **Monthly spending limit reached** | The month's spend hit the limit **you** set | Raise or remove the limit on the same page | | **AI features are paused — your credit has run out** | Pay as you go, and the balance reached zero | Add credit | | **All billable features are paused — your account has reached its debt limit** | The balance fell past the negative floor set for the account | Add credit; contact support if you need the floor changed | They are evaluated in that order, and you are told about the first that applies. Telling someone their credit ran out when they are actually suspended would send them to top up an account that will still refuse them. ```d2 direction: down classes: { q: { shape: diamond; width: 250 } stop: { width: 230; style.border-radius: 8 } ok: { width: 230; style.border-radius: 8 } } susp: "Suspended by Fours?" { class: q } limit: "Month's spend at\nyour own limit?" { class: q } model: "Monthly billing?" { class: q } floor: "Balance past the\ndebt limit?" { class: q } zero: "Balance at or\nbelow zero?" { class: q } s1: "AI, new sandboxes and\nuploads paused\nContact support" { class: stop } s2: "AI paused\nRaise or remove the limit" { class: stop } s3: "AI, new sandboxes and\nuploads paused\nAdd credit" { class: stop } s4: "AI paused\nAdd credit" { class: stop } run: "Requests run" { class: ok } susp -> s1: yes susp -> limit: no limit -> s2: yes limit -> model: no model -> run: "yes — never blocked\nfor balance" model -> floor: no floor -> s3: yes floor -> zero: no zero -> s4: yes zero -> run: no ``` **Monthly billing is never stopped for a balance.** The invoice comes after the usage, so a negative balance is the normal state of an invoiced account between invoices. It can still be stopped by a suspension or by your own spending limit. ## What keeps working This is the part people ask about first, and the answer is deliberate: **losing access to your own work over a few cents is not an acceptable billing outcome, and paying afterwards would not give back the hours you could not work.** | | Credit exhausted / limit reached | Past the debt limit | |---|---|---| | Reading, listing and searching your stored files | Works | Works | | Running sandboxes | Keep running | Keep running | | Starting, stopping, connecting to an existing sandbox | Works | Works | | **AI requests** | Paused | Paused | | **Creating a new sandbox** | Works | Paused | | **Uploading new files** | Works | Paused | **No data is deleted in any of these states.** A running sandbox is never killed to collect a debt. The difference between the two columns is the whole point of having two states: an exhausted balance is a soft stop that leaves you able to keep working with what you already have, and the debt limit is the hard stop that also prevents new capacity being reserved. ## What happens to a request in flight - **A request that has not started** is refused before the model is called, and answered in the conversation with the reason and what to do about it. This check sits on the paths that run a turn for you — chat, agent runs, and [jobs](/insulin/jobs/) — and on direct calls to a model: a [Custom App](/insulin/custom-apps/)'s own calls, and one-off AI suggestions in the Fours console, such as the AI suggestion button in a private offer's field-mapping configuration. A direct call has no conversation to answer in, so it fails with the same reason instead. - **A long response already streaming** is checked every ten seconds and cut off where the text stops, with the same explanation, once the balance is known to have run out. A deep research run or a multi-tool agent loop can otherwise spend far more than the balance it was allowed against. The check reads a decision that is held for up to a minute, so a response can run briefly past zero before it stops. - **If the check itself cannot be answered**, the response is allowed to finish rather than truncated. Consumption is metered either way, and losing an answer someone is waiting on is the worse failure. ## Resuming Service resumes **automatically** — there is nothing to switch back on and no operator to wait for. | Cause | Fix | Back within | |---|---|---| | Credit exhausted | Add credit | About a minute of the credit landing | | Debt limit | Add credit | About a minute of the credit landing | | Your monthly limit | Raise or remove it on **Settings → Billing** | About a minute | | Suspension | Fours lifts it — a successful payment does not clear it on its own | Immediately after | If you are relying on **automatic top-up** to add that credit, allow a little longer: the top-up itself runs every five minutes, and the minute above starts once it has been charged. The short delay is the spend check re-reading your account; it holds its answer for up to a minute so that a busy conversation is not re-checked on every message. :::warning **Adding credit does not clear your own spending limit.** If the banner names the *monthly spending limit*, topping up changes nothing — the limit is compared against what you have spent this month, not against your balance. Raise or remove the limit instead. ::: ## Being told before it happens The **Credit balance** card is the reliable early warning, and the in-app assistant can take you straight to **Settings → Billing** if you ask it about spend. If you would rather not watch it, turn on [automatic top-up](/insulin/billing/spend-controls/#turn-on-automatic-top-up): it charges a saved payment method once the balance is at or below a trigger you choose, so the balance never reaches zero in the first place. --- Source: https://doc.fours.com/insulin/billing/faq/ # Billing FAQ Questions about what your organization pays **Fours** for using Insulin. For billing the customers you sell to, see [Billing](/billing/). For help, contact [support@suger.io](mailto:support@suger.io). --- ## Credit ### How much free credit do we get? **$100 each month**, granted on the 1st. Some accounts have a different recurring amount arranged with Fours — the **Credit** table on **Settings → Billing** always shows the real figure for your organization. ### Does unused free credit roll over? No. Monthly free credit expires at the end of the month it was issued in. Credit you paid for is different: it stays valid for **three years**. ### We have several credits. Which one is spent first? The one expiring soonest. So the monthly free credit is used before credit you paid for, and paid credit is not wasted while free credit sits unused. The Credit table shows each grant, what is left of it, and when it expires. ### Can we buy credit in the console? Not directly. Credit is added by [automatic top-up](/insulin/billing/spend-controls/) against a saved payment method, or granted by Fours. Contact [support@suger.io](mailto:support@suger.io) to arrange a one-off purchase. ### Can we get a refund on credit we paid for? Contact support. Unspent credit can be reversed; credit already consumed cannot, and support can tell you which is which before anything is refunded. Refunds are issued in Stripe and then reflected on the account. ## Usage and cost ### How is AI usage measured? Input and output tokens are counted separately, per model and provider, and tagged with who or what caused them. Sandboxes bill processor, memory and storage independently. Object storage is sampled daily. [What is metered](/insulin/billing/metering/) has the detail. ### Why is the usage table empty when the balance went down? The usage breakdown is re-aggregated every couple of hours; the balance moves within about a minute. The usage will appear shortly. If the two disagree, the balance is the current one. ### We deleted everything. Why are we still billed for storage? Object storage is billed on the **highest** volume held on any single day of the month. Deleting reduces next month's peak, not this month's. The capacity was reserved on the day you used it, and the supplier charged for it then. ### We stopped a sandbox. Why is it still costing money? Stopping releases processor and memory but not the volume, which is still reserved for you — and the sandbox provider keeps charging Fours for it. **Delete the sandbox** to stop the storage charge. ### Are failed requests billed? Yes. The provider charges Fours for work it performed, whether or not the answer reached you. ### Is cached context billed? Yes, in full, as input tokens. Providers charge for cached context even when they serve it from cache. Today it is priced at the same rate as fresh input. ### Are we charged for AI that Fours runs itself? No. Platform features that use a model internally — summarization, search indexing, embeddings, reranking, field mapping — are Fours' cost. Only your use of Insulin is billed. ### What happens if we use a model Fours has no price for? It is still billed, at a documented fallback: a supplier cost of $5.00 per million input tokens and $10.00 per million output tokens, plus the standard 50% margin — so **$7.50** and **$15.00 per million** as charged. Newly released models are the usual case. Consumption is never dropped for want of a price. ### What currency, and is tax included? US dollars only, and amounts exclude tax — the billing platform does not calculate it. ## Bring your own key (BYOK) ### How does billing change if we use our own provider key? The provider bills you directly for the tokens under your own contract, and Fours charges a **flat fee per unit** rather than a percentage of a cost it does not incur. The platform still routes and secures every request and meters the token usage the provider reports — see [Using your own provider keys (BYOK)](/insulin/billing/metering/#using-your-own-provider-keys-byok) for when a reply may not be counted. ### We use our own key. Why were we blocked at a zero balance? Because the per-unit fee is still owed. A zero balance pauses AI requests on pay as you go whether the tokens were bought with Fours' key or your own. ## Limits and interruptions ### Why did AI stop for our organization? One of four reasons, named in the banner on **Settings → Billing**: a suspension, your own monthly spending limit, an exhausted balance, or the account's debt limit. [When AI pauses](/insulin/billing/when-ai-pauses/) explains each and how it resolves. ### We topped up and it is still blocked. Why? Almost always because the banner names your **monthly spending limit** rather than your balance. A limit is compared against what you have spent this month, not against your credit, so topping up changes nothing. Raise or remove the limit on the same page. ### Do our files or sandboxes get deleted when credit runs out? Never. Stored files stay readable and running sandboxes keep running. Past the account's debt limit, *new* sandboxes and *new* uploads also stop — but nothing existing is deleted. ### How quickly does service resume after adding credit? About a minute or two, automatically. No operator action is needed. ### Can we set a limit that warns without blocking? No. The monthly spending limit blocks when it is reached. To avoid reaching zero at all, use [automatic top-up](/insulin/billing/spend-controls/#turn-on-automatic-top-up). ## Invoices and payment ### When are we invoiced, and what does the invoice collect? Periods close on the 1st of the following month, and an invoice is issued for the closed period. What it collects depends on the billing model: - **Pay as you go** — nothing, in the normal case. The usage was already paid for as it happened, out of a credit balance you had funded, so the invoice is a statement. The exception is a balance that ended the month below zero, which is collected. - **Monthly billing** — the period's metered total, with any credit you hold applied against it on the document. Two things can stop an invoice being issued. Invoicing is enabled per account by Fours, and nothing is issued before it is — but pay-as-you-go usage still comes off your credit balance as it happens, so "no invoice yet" does not mean "free". An amount to collect below the payment provider's $0.50 minimum is also carried into a later period rather than charged. ### Where do we see past invoices? Not in the console — there is no invoice list on the billing page. Contact [support@suger.io](mailto:support@suger.io) for a copy of an invoice. ### What happens if a payment fails? Stripe retries up to four times on its own schedule. Nothing happens to the account during the retries. Once they are exhausted, a pay-as-you-go organization is suspended and notified; a monthly-billing organization is notified and Fours' team follows up, with no automatic cut-off. A suspension is not lifted automatically by a later successful payment — contact Fours to have it cleared. ### Do we need a payment method to use Insulin? No. The monthly free credit is spendable without one. You need a saved method to turn on automatic top-up, and monthly billing requires one. ### Can we change between pay as you go and monthly billing? Contact Fours. The change takes effect at the **start of the next month**, not immediately, and unused purchased credit carries across it. ## Access ### Who in our organization can see the billing page? Any member of a seller, reseller, or partner organization. **Settings → Billing** is not restricted to administrators, and there is no admin-only view within it. ### Can we reach it from inside Insulin? Yes — the **Settings** app on the Insulin desktop shows the same Billing tab as the console. The in-app assistant can also take you there if you ask it about billing or spend. --- Source: https://doc.fours.com/insulin/billing/ # Billing This section covers what your organization pays **Fours** for using Insulin, and how that figure is arrived at. Everything is consumption-based: there is no seat count, no tier and no subscription, so an organization that uses nothing pays nothing. Every organization starts on **pay as you go** with **$100 of free credit each month**, and no payment method is needed to spend it. It is not about billing the customers you sell to. That is [Billing](/billing/), where you meter, price, invoice, and collect from marketplace buyers — a separate ledger, and the one most often confused with this one. [How You Get Paid](/concepts/how-you-get-paid/) separates the two flows if you are unsure which you are looking at. Everything described here lives in one place: **Settings → Billing**, reachable from the Fours console and from the **Settings** app inside the [Insulin desktop](/insulin/). Any member of a seller, reseller, or partner organization can open it. ## Start here 1. **[How billing works](/insulin/billing/overview/)** — the two billing models, the monthly free credit, the order credit is spent in, and why a mid-month figure is an estimate. 2. **[What is metered](/insulin/billing/metering/)** — the six resources Fours measures, the unit each is measured in, how they are priced, and what is deliberately not billed. ## Watch what you are spending - **[Reading your usage](/insulin/billing/usage/)** — pivot one period by resource, user, app, model or provider; filter it; and read the daily spend chart. Every pivot totals the same amount, which is why unattributed consumption gets a row of its own. ## Keep it under control - **[Payment, limits, and top-ups](/insulin/billing/spend-controls/)** — add a payment method through Stripe's hosted page, set a monthly spending limit, and turn on automatic top-up so a task is not interrupted by a balance nobody was watching. - **[When AI pauses](/insulin/billing/when-ai-pauses/)** — the four reasons requests stop, what keeps working in each case (files and running sandboxes always do), and how service resumes. ## Reference - **[Billing FAQ](/insulin/billing/faq/)** — credit expiry, BYOK, why the usage table can look emptier than the balance, storage billed on the month's peak, and refunds. ## Scope and limits :::info **Prices are in US dollars and exclude tax.** There is no other currency, and the billing platform does not calculate tax. **The console does not sell credit or list invoices.** Credit is added by automatic top-up against a saved payment method, or granted by Fours. Invoices are issued for a closed period once Fours has enabled invoicing on the account, and are not browsed in the console; contact [support@suger.io](mailto:support@suger.io) for a copy. **Billing model, debt limit and suspension are set by Fours, not by you.** Your own controls are the monthly spending limit and automatic top-up. Changing a billing model takes effect at the start of the next month, never mid-period. ::: --- Source: https://doc.fours.com/insulin/ # Fours Insulin Fours Insulin is a general-purpose AI platform for business work, built by Fours — chat, agents, knowledge bases, jobs, and custom apps that teams across finance, sales, operations, support, and data use to run their daily work. It is built into the Fours console and opens as a desktop rather than a single chat page: each feature is its own app — Chat, Marketplace, Knowledge Base, Custom Apps, Files, Inbox, and more, plus Jobs — in a window you can move, resize, and keep open beside the others. Use it to ask about your offers, entitlements, co-sell deals, and revenue in plain language, to hand repeated work to an agent, and to build small internal tools without leaving Fours. Switch into it with the **insulin** wordmark in the console top bar; the **fours** wordmark in Insulin's System Bar takes you back, and your choice is remembered next time you sign in. Nothing else is needed to start — no API keys, no separate install — though an agent can only reach the third-party tools someone has connected in the **Settings** app. Insulin's product overview and pricing are on its own site, [insulin.dev](https://www.insulin.dev/). ## Start here 1. **[Getting Started](/insulin/getting-started/)** — the desktop, dock, and app launcher, the keyboard shortcuts, and how to move between the classic console and Insulin. 2. **[Agents](/insulin/agents/)** — the built-in Insulin assistant, plus catalog and custom agents with their own instructions, model, allowed integrations, skills, and knowledge bases, and the conversation you hold with one: streaming replies, tool calls, plan approvals, model selection, attachments, and memory. 3. **[Marketplace](/insulin/marketplace/)** — browse the catalog and install pre-built agents and skills, either privately or, as an org admin, for the whole organization. ## Ground answers in your own content - **[Knowledge Bases](/insulin/knowledge-base/)** — named collections of uploaded files, crawled websites, and synced connectors, indexed for hybrid vector and keyword search so an agent answers from your documents rather than from general knowledge. ## Bring your team into the conversation - **[Channels](/insulin/channels/)** — a shared thread where several teammates and several agents work in one place; `@mention` an agent to direct a question at it. Sending requires the USER role or higher. ## Ask from where you already work - **[Slack Bot](/insulin/slack-bot/)** — reach the same assistant from Slack: direct-message it, or `@mention` it in a channel to ask about your offers, entitlements and co-sell deals in the thread where the work is happening, or to hand a recurring task to a job. It asks before taking any action that reaches outside the conversation, and a channel conversation is read-only. ## Let work run without you - **[Jobs](/insulin/jobs/)** — one-off agent runs plus standing watches that fire on a cron schedule or on an incoming event, each leaving a run record you can open and inspect. - **[Inbox](/insulin/inbox/)** — connect Gmail or Outlook and let Insulin sort incoming mail into your own categories, then draft replies in your learned writing style for you to approve. Rules can also fire on a **CRM trigger** — a Salesforce opportunity, HubSpot deal, or Microsoft Dynamics 365 opportunity changing stage — to draft the follow-up email, DM you on Slack, or queue a CRM action for you to run. ## Build a tool instead of a chat - **[Custom Apps](/insulin/custom-apps/)** — describe the dashboard, form, or review screen you want, refine it with the AI builder, and share the result with your team. ## Know what it costs - **[Billing](/insulin/billing/)** — what your organization pays Fours for Insulin: the six metered resources, $100 of free credit every month, a live credit balance you can attribute by person, app or model, your own monthly spending limit and automatic top-up, and what pauses when the credit runs out. ## Scope and limits :::info **Inbox sends nothing on its own.** Every AI-drafted reply waits in **Approvals ▸ Pending** until you review it, and sending takes a second confirmation. The one exception is an auto-send rule you write yourself — and even that sends only when one exact filter matches, never puts your customer or knowledge-base data in what it sends, and holds anything its pre-send check flags for you to review. Inbox connects **either Gmail or Outlook** — both are supported, but only one can be the Inbox mailbox at a time, and switching between them deletes the old provider's stored mail. **Integrations are permissioned.** Any member can see the organization's integrations, but only an org admin can connect or disconnect them. Personal connections such as Gmail, Google Calendar, Google Drive, and Gong belong to you alone and are available only to your own agents and apps. **Insulin is licensed.** If your organization's license is invalid or expired, a banner appears across the top of the workspace; contact Fours at [sales@suger.io](mailto:sales@suger.io) to restore access. ::: --- Source: https://doc.fours.com/workflow/overview/ # Overview Fours’ Workflow Automation allows you to create custom processes for your operations that are not supported by the main product. With our library of pre-built workflow templates, you can deploy automations quickly—often requiring just a few tweaks or maybe none at all. ## Key Benefits: * **Extend Your Data Flows**: Automate data synchronization to your CRM on scenario with complex logic and many conditionals. * **Build Custom Automations**: Reduce reliance on manual processes and have up-to-date and synced data by leveraging our visual builder to connect with your various data platforms—such as Salesforce, HubSpot, Snowflake, Google Drive, NetSuite and more. Tailor integrations to fit your unique requirements and existing systems. * **Customize Notifications**: Design personalized notifications across channels like email, Microsoft Teams, and Slack to match your branding, and add extra logic to when and who you want to receive those notifications. * **Control Over Workflow Executions**: Gain complete command of your automation schedule with our flexible triggers. You can configure workflows to run immediately in response to real-time events, on a periodic schedule, via API calls from your system (webhooks), or even manually. Use the webhook triggers to also customize the input and output between Fours and your system's API. ## Use Cases: * **API-Driven Workflow Triggers**: Use webhook trigger to call the workflow from your API to automatically update the offer's contacts, EULA, commits, payment installments, etc. based on its associated quote and product. * **Tailored Private Offer Notifications**: Use fully customizable email templates to notify your customers about pending acceptance of private offers. This allows you to send detailed, branded messages covering offer terms, next steps, contact details, etc. * **Weekly Entitlement Reports to Google Drive**: Schedule a weekly workflow that collates a summary of active and canceled entitlements. The data is formatted into a CSV file and automatically sent to your Google Drive, enabling you to conduct custom analysis with minimal manual effort. --- Source: https://doc.fours.com/workflow/getting-started/ # Getting Started with Workflows Automate repetitive marketplace tasks by building workflows that react to events, apply your rules, and take action across your connected tools. --- ## Overview Every workflow follows the same three-part logic. Understanding this structure before you build makes it easier to plan what each workflow needs to do: 1. **Trigger:** An event that starts the workflow, such as a referral approval, a new private offer, or a completed transaction. 2. **Conditions:** Rules that control when the workflow runs. For example, only fire if the cloud partner is AWS and the deal value is above $50,000. 3. **Actions:** What happens when the trigger and conditions are met, such as sending a Slack message, updating a CRM field, or uploading a report to Google Drive. You have two ways to get started: begin from a pre-built template, or build a custom workflow from scratch in the visual builder. ## Option 1: Start from a template If your use case is common, templates are the fastest way to get a workflow running. Templates come pre-configured with the core logic already in place, so you only need to adjust a few settings before activating. ### Access the template library 1. Go to **Workflows** in the Fours Console. 2. Click the **Templates** tab to browse available automations by category (Reporting, Notifications, CRM Sync). ### Available templates * **Private offer notifications:** Sends branded email alerts to customers when a private offer is pending, including offer terms and contact details. * **Weekly entitlement report:** Runs on a schedule to compile active and canceled entitlements into a CSV file and upload it to Google Drive or Snowflake. * **API-driven updates:** Uses a webhook trigger to connect Fours to your internal systems, so your API can automatically update offer contacts or EULA terms. ### Activate a template 1. Select a template to open it in the visual builder. The core logic is already filled in. 2. Verify the destination settings, such as your Slack channel name or email domain. 3. Choose how the workflow fires: by a real-time event (Webhook), on a schedule (Cron), or manually. 4. Toggle the workflow to **Active**. ## Option 2: Build a custom workflow For automations that go beyond what templates offer, you can build your own workflow from scratch in the visual builder. ### Plan your workflow first Before opening the builder, take a few minutes to define the following. This prevents common issues like missing data fields or unclear logic once you start connecting nodes. * **What problem does this solve?** State the manual or repetitive task you are automating. For example: "AEs have to manually check for referral approvals and notify the team." * **What does success look like?** Define the expected outcome. For example: "AEs receive a Slack message with AWS contact details within 5 minutes of a referral being approved." * **Where does the trigger come from?** Identify the origin system, such as the Fours Console, Salesforce, or the AWS Partner Central API. * **What data is needed?** List every field required to complete the action, such as Opportunity Owner, AWS Account Manager, Customer Name, and Deal Context. Missing fields will cause the workflow to fail silently. * **When should it not run?** Define any exceptions, such as "skip if no Account Manager is assigned" or "only run for deals above $50,000." ### Build the workflow 1. Go to **Workflows** in the Fours Console. 2. Click **New Workflow** to open the visual builder canvas. 3. Drag a **Trigger** node onto the canvas and configure the event that starts the workflow. 4. Add **Condition** nodes to define the rules that control when the workflow proceeds. 5. Add **Action** nodes to define what happens at the end of the workflow, such as sending a notification or updating a record. 6. Connect nodes to external platforms as needed. Supported integrations include Salesforce, HubSpot, NetSuite, Snowflake, and Google Drive. :::info To trigger a workflow from your own internal systems, use a [Webhook](/workflow/webhook) trigger node. This lets your applications call a Fours workflow directly to update offer terms, EULA details, or payment installments in real time. ::: ### Test before publishing 1. Use the built-in test tool to simulate an event through the workflow. 2. Confirm that each node processes correctly and that conditional branches behave as expected. 3. Check that data outputs from the trigger (such as an Opportunity ID) are correctly mapped to the inputs of your action nodes. ### Publish the workflow Once testing passes, click **Publish** to activate the workflow. ## Monitor workflow runs After a workflow is live, use **Execution History** in the Fours Console to track every run in real time. If a workflow fails, the logs show which node encountered the issue and what data was present at that point, making it easier to identify and fix the problem. --- Source: https://doc.fours.com/workflow/aggregate/ # Aggregate Combine and process data from multiple inputs. --- ## Overview The Aggregate node is a powerful data processing tool that combines multiple input items into a consolidated output. It's particularly useful when you need to merge data from different sources, extract specific fields, or combine lists from multiple items. ## Operations The Aggregate node supports two main modes of operation: ### Individual Fields Aggregation Aggregate specific fields from multiple input items with precise control over the output. #### Configuration Options: - **Field Selection**: - Source Field: The field to aggregate from input items - New Field Name: Custom name for the aggregated field - Dot Notation Support: Access nested fields (e.g., "user.name") - **Processing Options**: - Keep Missing Values: Include fields even if missing in some items - Keep Only Unique: Remove duplicate values from the output - Merge Lists: Combine arrays from different items - Include Binaries: Option to include binary data ### All Fields Aggregation Combine all fields from multiple input items into a single output structure. #### Configuration Options: - **Destination Settings**: - Destination Field: Name of the field to store combined data (default: "data") - Include Fields: Specify fields to include in the aggregation - Exclude Fields: Specify fields to exclude from the aggregation - **Processing Options**: - Keep Missing Values: Include fields even if missing in some items - Keep Only Unique: Remove duplicate values from the output - Merge Lists: Combine arrays from different items - Include Binaries: Option to include binary data ## Common Use Cases 1. **Data Consolidation** - Merge user data from multiple sources - Combine related records into a single view - Aggregate statistics or metrics 2. **List Processing** - Merge arrays from different items - Remove duplicates from combined lists - Process nested data structures 3. **Field Extraction** - Extract specific fields from multiple records - Rename fields for better organization - Handle complex nested data structures ## Best Practices 1. **Field Naming** - Use clear, descriptive names for output fields - Avoid duplicate field names in the output - Use dot notation carefully for nested structures 2. **Data Processing** - Consider enabling "Keep Only Unique" when dealing with potential duplicates - Use "Keep Missing Values" when all data points are important - Be mindful of memory usage when processing large datasets 3. **Performance** - Limit the number of fields when using All Fields Aggregation - Use Individual Fields Aggregation for specific needs - Consider the impact of binary data inclusion ## Example For example, if you have three input items with the following data(can generate using the [`Fours Code`](/workflow/suger-code) node): ```json [ { "json": { "num": 1 } }, { "json": { "num": 2 } }, { "json": { "num": 3 } } ] ``` You can configure the Aggregate node to combine these into a single output item with the following settings: ![Aggregate Node Configuration](images/aggregate.png) then, it will generate the following output: ```json [ { "json": { "num2": [1, 2, 3] } } ] ``` --- Source: https://doc.fours.com/workflow/chargebee/ # Chargebee Use the Chargebee node to manage customers, invoices, and subscriptions in Chargebee. --- ## Operations The Chargebee node supports operations on three main resources: Customer, Invoice, and Subscription. ### Customer Operations #### Create Customer Create a new customer in Chargebee with the following properties: - User ID: Custom ID for the customer, if not given, this will be auto-generated - First Name: Customer's first name - Last Name: Customer's last name - Email: Customer's email address - Phone: Customer's phone number - Company: Customer's company name - Custom Properties: (Additional custom name-value fields): - Property Name - Property Value #### List Customers Retrieve a list of customers with optional filtering: - Max Results: Number of results to return (1-100, default: 10) - Filters: - Field (First Name, Last Name, or Email) - Operation (Is, Is Not, Starts With, In, Not In, Is Present) - Value(s) based on the chosen operation ### Invoice Operations #### List Invoices Retrieve a list of invoices with filtering options: - Max Results: Number of results to return (1-100, default: 10) - Filters: - Invoice Date: - Operation: Is, Is Not, After, Before - Date: The reference date for filtering - Invoice Amount: - Operation: Greater Than, Less Than, Equal To, etc. - Amount: The reference amount for filtering #### Get PDF Invoice URL Retrieve the PDF URL for a specific invoice: - Invoice ID (required): The ID of the invoice to get the PDF URL for ### Subscription Operations #### Cancel Subscription Cancel an existing subscription: - Subscription ID (required): The ID of the subscription to cancel - Schedule End of Term: Whether to cancel immediately or at the end of the billing period #### Delete Subscription Delete a subscription: - Subscription ID (required): The ID of the subscription to delete --- Source: https://doc.fours.com/workflow/delete-execution/ # Delete Execution Delete unnecessary execution data. --- Fours recommends avoiding the storage of unnecessary data to prevent excessive growth of the database. For instance, execution data generated by a Snowflake node that queries and updates database records typically is not required for subsequent processing, as these operations have already been completed. ## Operations This node has no parameters. Just put it at the end of the workflow to delete the execution data. Delete Execution workflow node The execution data will **NOT** be saved and will **NOT** be shown in the **Executions** tab. --- Source: https://doc.fours.com/workflow/filter/ # Filter Remove data items matching conditions. ## Overview The Filter node allows you to define conditions, and when the data items match these conditions, they will be removed from the workflow. ## Usage 1. Add the Filter node to your workflow in Fours. 2. Configure conditions to evaluate incoming data. 3. Connect downstream node to the output of this node. 4. Save and activate the workflow. ## Configuration ### Add Conditions - **Data Type**: Select the type (e.g., String, Number, Date) for comparison. - **Comparison**: Choose an operation (e.g., `is equal to`, `is greater than`). - **Value**: Enter the value to compare against. - **Combination**: Use `AND` or `OR` to combine multiple conditions. ### Options - **Ignore Case**: Toggle to make string comparisons case-insensitive. - **Less Strict Type Validation**: Toggle to allow flexible type matching (e.g., comparing a string "123" to a number 123). Filter node configuration panel with conditions and options ### Available Comparisons #### String - exists - does not exist - is equal to - is not equal to - contains - does not contain - starts with - does not start with - ends with - does not end with - matches regex - does not match regex #### Number - exists - does not exist - is equal to - is not equal to - is greater than - is less than - is greater than or equal to - is less than or equal to #### Date & Time - exists - does not exist - is equal to - is not equal to - is after - is before - is after or equal to - is before or equal to #### Boolean - exists - does not exist - is true - is false - is equal to - is not equal to #### Array - exists - does not exist - is empty - is not empty - contains - does not contain - length equal to - length not equal to - length greater than - length less than - length greater than or equal to - length less than or equal to #### Object - exists - does not exist - is empty - is not empty --- Source: https://doc.fours.com/workflow/form-trigger/ # Form Trigger Create forms to trigger workflows. --- The Form Trigger node allows you to start a workflow when a user submits a form. When you add this node to your workflow: 1. It automatically generates a web form page 2. The form's submitted data becomes available in your workflow 3. The workflow executes immediately upon form submission ## Usage 1. Add the Form Trigger node to your workflow 2. Configure the form fields in the node settings 3. Save and activate the workflow 4. Use the generated form URL to collect responses The form data will be available in subsequent nodes as JSON key-value pairs. ## Form Configuration The Form Trigger node provides comprehensive form customization through the following settings: ### Basic Settings - **Form Title**: The heading displayed at the top of your form - **Form Description**: Additional context or instructions shown below the title - **Form URLs**: The unique URL where your form can be accessed ### Visual Customization - **Company Logo**: Upload your organization's logo to display on the form - **Background Image**: Add a custom background image to enhance the form's appearance ### Form Fields Add and configure form fields of the following types: - **Text**: Single-line text input - **Textarea**: Multi-line text input for longer responses - **Email**: Input field with email validation - **Number**: Numeric input with optional min/max values - **Date**: Date picker with calendar interface - **Dropdown List**: Select from predefined options - **Password**: Secure password input field with masked characters ### Form Response Configure what happens after form submission: - **Redirect URL**: Send users to a specific webpage after submitting - **Success Message**: Display a custom thank you or confirmation message --- Source: https://doc.fours.com/workflow/google-big-query/ # Google BigQuery Execute insert and query operations on Google BigQuery. --- Google BigQuery is a fully managed, serverless data warehouse that enables super-fast SQL queries and real-time analytics over petabytes of data. See [Google BigQuery](https://cloud.google.com/bigquery) for more details. The Google BigQuery integration must be configured before using this node. See [Google BigQuery Integration](/integrations/bigquery) for more details. ## Operations ### Insert #### Parameters - **Project**: Select or input the ID or URL of the project. - **Dataset**: Select or input the ID of the dataset. - **Table**: Select or input the ID of the table. - **Data Mode**: - **Auto-Map Input Data**: Used when the node input data properties match the table field names. In this mode, make sure the incoming data fields are named the same as the columns in BigQuery. - **Map Each Field Below**: Define a mapping of the node input data properties to the table field names. Field mapping configuration for BigQuery Insert operation #### Options - **Batch Size**: The number of rows to insert in each batch. - **Ignore Unknown Values**: Whether to ignore row values that do not match the table schema. - **Skip Invalid Rows**: Whether to skip rows with values that do not match the table schema. - **Template Suffix**: Create a new table based on the destination table and insert rows into the new table. The new table will be named `${destinationTable}${templateSuffix}` - **Trace ID**: Unique ID for the request, for debugging only. It is case-sensitive, limited to up to 36 ASCII characters. A UUID is recommended. ### Execute Query #### Parameters - **Project**: Select or input the ID or URL of the project. - **SQL Query**: The SQL query to execute. [Standard SQL syntax](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax) is used by default, but you can also use [Legacy SQL syntax](https://cloud.google.com/bigquery/docs/reference/legacy-sql) by using the option 'Use Legacy SQL'. #### Options - **Default Dataset Name or ID**: If not set, all table names in the query string must be qualified in the format 'datasetId.tableId'. - **Dry Run**: When set to true, BigQuery doesn't actually run the job. Instead, if the query is valid, BigQuery returns statistics about the job such as how many bytes would be processed. If the query is invalid, an error returns. - **Include Schema in Output**: Whether to include the schema in the output. If set to true, the output will contain key `_schema` with the schema of the table. - **Location (Region)**: Location or the region where data would be stored and processed. Pricing for storage and analysis is also defined by location of data and reservations, more information about [BigQuery locations](https://cloud.google.com/bigquery/docs/locations). - **Maximum Bytes Billed**: Limits the bytes billed for this query. Queries with bytes billed above this limit will fail (without incurring a charge). String in [Int64Value](https://developers.google.com/discovery/v1/type-format?utm_source=cloud.google.com&utm_medium=referral) format. - **Max Results**: The maximum number of rows of data to return. - **Timeout**: How long to wait for the query to complete in milliseconds. - **Raw Output**: Whether to return the raw output of the query. - **Use Legacy SQL**: Whether to use BigQuery's legacy SQL dialect for this query. If set to false, the query will use BigQuery's standard SQL. --- Source: https://doc.fours.com/workflow/google-cloud-storage/ # Google Cloud Storage Automatation on cloud storage buckets and objects. --- Google Cloud Storage allows you to automate operations with cloud storage buckets and objects, enabling seamless integration with other applications and services. You need to connect your Google Cloud Storage account to Fours to use this node. See [Google Cloud Storage Integration](/integrations/google-cloud-storage) for more details. ## Operations ### Bucket Operations - Create: Creates a new storage bucket with specified configurations like location, storage class, and access controls - Delete: Permanently removes a storage bucket and all its contents - Get: Retrieves metadata and properties of a specific bucket - Get Many: Lists multiple buckets in your project with optional filtering - Update: Modifies bucket properties such as lifecycle rules, IAM policies, or storage class ### Object Operations - Create: Uploads new files (objects) to a specified bucket with optional metadata - Delete: Removes objects from a bucket, with support for single or batch deletions - Get: Downloads an object or retrieves its metadata from a bucket - Get Many: Lists multiple objects within a bucket with optional prefix filtering - Update: Modifies object properties like metadata, storage class, or access controls ## Additional Resources - [Google Cloud Storage Documentation](https://cloud.google.com/storage/docs) - [Best Practices for Google Cloud Storage](https://cloud.google.com/storage/docs/best-practices) - [Pricing Information](https://cloud.google.com/storage/pricing) --- Source: https://doc.fours.com/workflow/google-drive/ # Google Drive Automate file and folder operations on Google Drive. --- Google Drive allows you to automate operations with Google Drive files and folders, enabling seamless integration with other applications and services. You need to connect your Google Drive account to Fours to use this node. See [Google Drive Integration](/integrations/google-drive) for more details. ## Operations ### File Operations #### Copy a File - Creates a duplicate of an existing file in Google Drive - Allows you to specify a new name and location for the copy - Preserves all original file content and formatting ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Copy**. - **File**: Select the source file using one of these methods: - **Select From List**: Choose from available files in the dropdown - **By URL**: Paste the Google Drive file URL - **By ID**: Enter the file ID directly > Tip: To find a file ID, open the file in Google Drive and copy its sharing link. The ID is the string between 'd/' and '/edit' in the URL. - **File Name**: Enter a name for the new copy - **Copy In The Same Folder**: Toggle to keep the copy in the original file's location ##### Options - **Copy Requires Writer Permission**: When enabled, only users with edit access can copy, print, or download the file - **Description**: Add an optional description for the new file --- #### Create from Text - Creates a new file directly from text content - Specify the file name, content, and optional destination folder - Supports various text formats (plain text, markdown, etc.) - Option to convert to Google Document format ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Create from Text**. - **File Content**: Enter the text content for the new file - **File Name**: Enter a name for the new file - **Parent Drive**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the drive URL - **By ID**: Enter the driveId directly > Tip: Find the driveId in the URL: `https://drive.google.com/drive/u/1/folders/[driveId]` - **Parent Folder**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the folder URL - **By ID**: Enter the folderId directly ##### Options - **APP Properties**: Add private key-value pairs (visible only to the requesting app) - **Properties**: Add public key-value pairs (visible to all apps) - **Keep Revision Forever**: Pin this revision (binary content only, max 200 revisions) - **OCR Language**: Specify ISO 639-1 language code for OCR interpretation - **Use Content As Indexable Text**: Enable text indexing for the content - **Convert to Google Document**: Create as Google Doc instead of .txt (requires Google Docs API) --- #### Delete a File - Permanently removes a file from Google Drive - Option to skip the trash and delete permanently - Supports deletion by file ID ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Delete**. - **File**: Select the source file using one of these methods: - **Select From List**: Choose from available files in the dropdown - **By URL**: Paste the Google Drive file URL - **By ID**: Enter the file ID directly > Tip: To find a file ID, open the file in Google Drive and select Share > Copy link. The ID is the string between 'd/' and '/edit' in the URL. ##### Options - **Delete Permanently**: When enabled, bypasses the trash and permanently deletes the file --- #### Download a File - Downloads a file from Google Drive to your local system - Supports various file formats - Option to specify download location and format ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Download**. - **File**: Select the source file using one of these methods: - **Select From List**: Choose from available files in the dropdown - **By URL**: Paste the Google Drive file URL - **By ID**: Enter the file ID directly > Tip: To find a file ID, open the file in Google Drive and select Share > Copy link. The ID is the string between 'd/' and '/edit' in the URL. ##### Options - **Put Output File in Field**: Specify the field name to store the binary file contents - **Google File Conversion**: Select export formats for Google Workspace files: - **Google Docs**: Export as HTML, MS Word Document, Open Office Document, PDF, Rich Text (rtf), or Text (txt) - **Google Drawings**: Export as JPEG, PDF, PNG, or SVG - **Google Slides**: Export as MS PowerPoint, OpenOffice Presentation, or PDF - **Google Sheets**: Export as CSV, MS Excel, Open Office Sheet, or PDF - **File Name**: Specify the name for the downloaded file --- #### Move a File - Relocates a file to a different folder in Google Drive - Updates the file's parent folder - Maintains file properties and sharing settings ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Move**. - **File**: Select the source file using one of these methods: - **Select From List**: Choose from available files in the dropdown - **By URL**: Paste the Google Drive file URL - **By ID**: Enter the file ID directly > Tip: To find a file ID, open the file in Google Drive and select Share > Copy link. The ID is in the URL: `https://docs.google.com/document/d/[fileId]/edit` - **Parent Drive**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the drive URL - **By ID**: Enter the driveId directly > Tip: Find the driveId in the URL: `https://drive.google.com/drive/u/1/folders/[driveId]` - **Parent Folder**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the folder URL - **By ID**: Enter the folderId directly --- #### Share a File - Manages access permissions for a file - Set various permission levels (view, edit, comment) - Share with specific users, groups, or make public ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Share**. - **File**: Select the source file using one of these methods: - **Select From List**: Choose from available files in the dropdown - **By URL**: Paste the Google Drive file URL - **By ID**: Enter the file ID directly > Tip: To find a file ID, open the file in Google Drive and select Share > Copy link. The ID is in the URL: `https://docs.google.com/document/d/[fileId]/edit` - **Permissions**: Configure access settings: - **Role**: Choose permission level: - Commenter - File Organizer - Organizer - Owner - Reader - Writer - **Type**: Select permission scope: - **User**: Share with specific user (requires Email Address) - **Group**: Share with group (requires Email Address) - **Domain**: Share with entire domain (requires Domain) - **Anyone**: Make public (optional: Allow File Discovery) ##### Options - **Email Message**: Add custom text to notification email - **Move to New Owners Root**: When transferring ownership, moves file to new owner's My Drive - **Send Notification Email**: Toggle email notifications for users/groups - **Transfer Ownership**: Transfer ownership to specified user (downgrades current owner to writer) - **Use Domain Admin Access**: Perform action as domain administrator --- #### Update a File - Modifies existing file properties or content - Update metadata, description, or file content - Maintain version history ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Update**. - **File**: Select the file to update using one of these methods: - **Select From List**: Choose from available files in the dropdown - **By URL**: Paste the Google Drive file URL - **By ID**: Enter the file ID directly > Tip: To find a file ID, open the file in Google Drive and select Share > Copy link. The ID is in the URL: `https://docs.google.com/document/d/[fileId]/edit` - **Change File Content**: Toggle to update the file's binary content - **Input Data Field Name**: Specify the field containing the new binary data - **New Updated File Name**: Optional new name for the file ##### Options - **APP Properties**: Add private key-value pairs (visible only to the requesting app) - **Properties**: Add public key-value pairs (visible to all apps) - **Keep Revision Forever**: Pin this revision (binary content only, max 200 revisions) - **OCR Language**: Specify ISO 639-1 language code for OCR interpretation - **Use Content As Indexable Text**: Enable text indexing for the content - **Move to Trash**: Move file to trash (file owner only) - **Return Fields**: Select metadata fields to return: - All - explicitlyTrashed - exportLinks - hasThumbnail - iconLink - ID - Kind - mimeType - Name - Permissions - Shared - Spaces - Starred - thumbnailLink - Trashed - Version - webViewLink --- #### Upload a File - Uploads local files to Google Drive - Specify destination folder and file properties - Support for various file types and sizes ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Upload**. - **Input Data Field Name**: Specify the field containing the binary file data - **File Name**: Enter a name for the uploaded file - **Parent Drive**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the drive URL - **By ID**: Enter the driveId directly > Tip: Find the driveId in the URL: `https://drive.google.com/drive/u/1/folders/[driveId]` - **Parent Folder**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the folder URL - **By ID**: Enter the folderId directly ##### Options - **APP Properties**: Add private key-value pairs (visible only to the requesting app) - **Properties**: Add public key-value pairs (visible to all apps) - **Keep Revision Forever**: Pin this revision (binary content only, max 200 revisions) - **OCR Language**: Specify ISO 639-1 language code for OCR interpretation - **Use Content As Indexable Text**: Enable text indexing for the content - **Simplify Output**: Return a simplified response without all fields ### Folder Operations #### Create a Folder - Creates a new folder in Google Drive - Specify folder name and optional parent folder - Set initial sharing permissions ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Create**. - **Folder Name**: Enter a name for the new folder - **Parent Drive**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the drive URL - **By ID**: Enter the driveId directly > Tip: Find the driveId in the URL: `https://drive.google.com/drive/u/1/folders/[driveId]` - **Parent Folder**: Choose one of: - **Select From List**: Choose from the dropdown - **By URL**: Enter the folder URL - **By ID**: Enter the folderId directly ##### Options - **Simple Output**: Return a simplified response without all fields - **Folder Color**: Select a color for the folder --- #### Delete a Folder - Permanently removes a folder and all its contents - Option to skip the trash and delete permanently - Confirmation required for non-empty folders ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Delete**. - **Folder**: Select the folder to delete using one of these methods: - **Select From List**: Choose from available folders in the dropdown - **By URL**: Enter the folder URL - **By ID**: Enter the folderId directly ##### Options - **Delete Permanently**: When enabled, bypasses the trash and permanently deletes the folder --- #### Share a Folder - Manages access permissions for a folder - Set permissions for the folder and its contents - Share with users, groups, or make public ##### Parameters - **Resource**: Select **File**. - **Operation**: Select **Share**. - **Folder**: Select the folder to share using one of these methods: - **Select From List**: Choose from available folders in the dropdown - **By URL**: Enter the folder URL - **By ID**: Enter the folderId directly - **Permissions**: Configure access settings: - **Role**: Choose permission level: - Commenter - File Organizer - Organizer - Owner - Reader - Writer - **Type**: Select permission scope: - **User**: Share with specific user (requires Email Address) - **Group**: Share with group (requires Email Address) - **Domain**: Share with entire domain (requires Domain) - **Anyone**: Make public (optional: Allow File Discovery) - **Domain**: The domain to share with - **Allow File Discovery**: When enabled, allows users to find the shared file in search results ##### Options - **Email Message**: Add custom text to notification email - **Move to New Owners Root**: When transferring ownership, moves folder to new owner's My Drive - **Send Notification Email**: Toggle email notifications for users/groups - **Transfer Ownership**: Transfer ownership to specified user (downgrades current owner to writer) - **Use Domain Admin Access**: Perform action as domain administrator --- ## Additional Resources - [Google Drive API Reference](https://developers.google.com/drive/api/reference/rest/v3) - [Google Drive Developer Guides](https://developers.google.com/drive/api/guides/about-sdk) --- Source: https://doc.fours.com/workflow/google-mail/ # Google Mail Send emails using Gmail. --- The Google Mail node allows you to automate email operations in Gmail. Before using this node, you'll need to connect your Google Mail account to Fours. See [Google Mail Integration](/integrations/google-mail) for more details. ## Parameters ### To Email (Required) The primary recipient's email address. Can be set as a fixed value or using an expression. Example: `info@example.com` ### CC Email List (Optional) Additional recipients to be CC'd on the email. Multiple email addresses can be added. Can be set as fixed values or using expressions. Use the "Add Cc Email" button to add more recipients. ### Subject (Required) The subject line of the email. Can be set as a fixed value or using an expression. Example: "My email subject" ### Email Format Choose from three format options: 1. **Text** - Send email as plain text - Best for simple, text-only messages 2. **HTML** (Default) - Send email as HTML - Supports rich formatting, images, and styling 3. **Both** - Sends both HTML and plain text versions - Email client determines which version to display - Recommended for maximum compatibility ### Text Plain text message content. This field appears when Email Format is set to "Text" or "Both". Can be set as a fixed value or using an expression. ### HTML Source When Email Format is set to "HTML" or "Both", choose how to provide the HTML content: #### Manual Input The HTML content of your email when using Manual Input mode. This field supports both fixed values and expressions. #### AI Generated Use AI to generate professional HTML email content dynamically. The following parameters are available: AI Generated HTML email parameters in the Google Mail node ##### LLM Provider Select the AI provider to use for generating HTML email content: - **Anthropic**: Claude AI models (Default) - **OpenAI**: GPT models - **Gemini**: Google's Gemini models ##### System Prompt Enter the system prompt that instructs the AI how to generate HTML email content. This defines the AI's behavior and output format. The default system prompt ensures the AI returns only clean, professional HTML content suitable for email templates. ##### User Prompt Enter a prompt describing what kind of HTML email content to generate based on the input data. The AI will generate appropriate HTML content based on the input data and this prompt. For example: "Create a professional email template with the deal information including company name, deal value, and a call-to-action button linking to: https://console.suger.io/cosellv2/azure/{info.id}" :::info By integrating your [OpenAI](../7.integrations/openai.md) / [Gemini](../7.integrations/google-gemini.md) / [Anthropic](../7.integrations/anthropic.md) account with Fours, you can utilize your own API keys. This allows you to access AI-powered features within Fours at your own cost but without Fours' usage limitations, with billing for API usage handled directly by the LLM provider. ::: ## Examples ### Sending a Plain Text Email 1. Set **Email Format** to `Text` 2. Enter recipient in **To Email** field 3. Add **Subject** line 4. Enter message content in **Text** field ### Sending an HTML Email (Manual) 1. Set **Email Format** to `HTML` 2. Set **HTML Source** to `Manual Input` 3. Enter recipient in **To Email** field 4. Add **Subject** line 5. Enter HTML content in **HTML** field ### Sending AI Generated HTML Email 1. Set **Email Format** to `HTML` or `Both` 2. Set **HTML Source** to `AI Generated` 3. Enter recipient in **To Email** field 4. Add **Subject** line 5. Choose your preferred **LLM Provider** (Anthropic, OpenAI, or Gemini) 6. Configure the **System Prompt** to define AI behavior. Example: ```markdown You are a professional email HTML generator. Create complete, well-formatted HTML emails that work across email clients. RESPONSE REQUIREMENTS: 1. Generate a COMPLETE HTML email document with proper structure 2. Include , , , and tags 3. Add responsive meta tags and email-safe CSS in 4. Use inline CSS for maximum email client compatibility 5. Create professional, clean design with proper spacing and typography 6. Include responsive design for mobile devices 7. Use email-safe fonts and avoid complex CSS features 8. Structure content with proper headings, paragraphs, and tables 9. Add proper alt text for images and accessibility features 10. Return ONLY the HTML code - no explanatory text or markdown DESIGN GUIDELINES: - Use tables for layout structure (email client compatibility) - Apply inline styles to all elements - Use web-safe fonts: Arial, Helvetica, sans-serif - Include proper spacing with padding and margins - Ensure text is readable with good contrast - Keep email width around 600px for best compatibility Generate a complete, professional HTML email ready to send. ``` 7. Enter your **User Prompt** describing what email content to generate. Example: ```markdown Display important information about the offer. Use AWS theme color #F26A1C. Include action button linking to: https://console.suger.io/offer/{entityID} Include footer with logo (https://imagedelivery.net/pNNvR2_tZYczcQ3leBU_1A/f058b32c-097e-4ba8-b3a4-700d14261300/public), 'Powered by Suger' text with link to suger.io, and copyright '© Suger, Inc.'. ``` 8. The AI will automatically generate professional HTML email content based on your input data ### Sending Both Text and HTML Email 1. Set **Email Format** to `Both` 2. Configure both **Text** content and **HTML Source** settings 3. This provides maximum compatibility across email clients ## Usage Tips - Multiple email addresses in CC fields should be comma-separated - When using AI Generated HTML, the content is automatically optimized for email clients - Use expressions to dynamically populate email content with workflow data - Consider using the "Both" format option for better email client compatibility - AI-generated content works best with structured data inputs --- Source: https://doc.fours.com/workflow/google-sheet/ # Google Sheet Manipulate Google Sheets. --- To target a specific sheet, select the desired Document and Sheet using the dropdown list, or enter their ID or name manually. Google Sheet node with Document and Sheet dropdowns ## Operations The Google Sheet node supports operations on a single resource: **Sheet Within Document**. ### Sheet Within Document Operations #### Get Rows Retrieves data from a sheet in JSON format. Column names are extracted from the header row and used as keys, and each subsequent row is converted into a JSON object where the cell values become the corresponding values. For example, given the following sheet: | fruit | price | |---------|-------| | Apple | 1.20 | | Banana | 0.80 | | Orange | 1.00 | The output will be: ```json [ { "fruit": "Apple", "price": "1.20" }, { "fruit": "Banana", "price": "0.80" }, { "fruit": "Orange", "price": "1.00" } ] ``` You can configure the following options: - **Data Location on Sheet** *(optional)*: - **Header Row**: Index of the row containing column names (defaults to `1`). - **First Data Row**: Index of the first row containing actual data (defaults to `2`). #### Update Rows Updates data in the sheet using the output from the previous node in the workflow. The input must be a list of JSON objects where each object includes: - A `"row_number"` field indicating the row to update. - Keys that match the column names of the sheet, or specify a column by index using the syntax `col_` (index starts at 1). For example: ```json [ { "row_number": 3, "fruit": "Strawberry", "col_2": 1.20 }, { "row_number": 4, "fruit": "Pineapple", "col_2": 2.50 } ] ``` In this example: - Rows 3 and 4 will be updated. - The cells under the “fruit” column, for rows 3 and 4, will be set to `Strawberry` and `Pineapple`, respectively. - The cells under second column ("price", as per the above table), for rows 3 and 4, will be set to `1.20` and `2.50`, respectively. You can configure the following options: - **Data Location on Sheet** *(optional)*: - **Header Row**: Index of the row containing column names (defaults to `1`). - **First Data Row**: Index of the first row containing actual data (defaults to `2`). > Notes: > - Entries without a `"row_number"` field will be ignored. > - Keys that don't match existing column names **will be ignored**, unless they use the `col_` syntax to explicitly target a column by its position (starting at 1). > - If a specified row number doesn't yet exist, the sheet will be extended to accommodate it. #### Clear Rows Clears a specified range of rows from the sheet. You can configure the following option: - **Range**: The cell range to clear. Example: `A3:C4` --- Source: https://doc.fours.com/workflow/html/ # HTML Generating HTML templates and extracting data from HTML. --- ## Operations The HTML node supports two main operations for working with HTML content: ### Generate HTML Template Create HTML content using a template with support for dynamic expressions. #### Configuration Options: - **HTML Template**: The HTML content to render, supporting: - HTML5 tags - `