openapi: 3.0.3 info: title: Headless API description: 'This API provides headless capabilities for managing the quote lifecycle within DealHub. It allows for the programmatic simulation and generation of quotes, as well as performing actions such as submitting for approval, publishing, and signing. All requests require a secret Bearer Token in the `Authorization` header.' version: 1.0.0 servers: - url: https://api.dealhub.io description: The base URL for your DealHub instance. security: - bearerAuth: [] tags: - name: Headless Quoting description: Endpoints for programmatic quote simulation, generation, and lifecycle actions. paths: /api/v1/quote/simulate: post: tags: - Headless Quoting summary: Simulate a Quote description: "Synchronously calculates quote pricing and details based on the provided configuration without creating\ \ a persistent quote object in DealHub. Ideal for real-time price calculations.\n\nUse this endpoint to calculate\ \ real-time pricing and quote details without creating a permanent record in DealHub. You have to inform the product\ \ and configuration data to receive the calculated line items and a financial summary. \n\nTo run a simulation, your\ \ request must include a `version_id` to specify which pricing and product rules to use. You also need to provide\ \ one of the following options:\n\n- `external_opportunity_id`: Use this to base the simulation on an existing opportunity\ \ in your CRM.\n- `geo_code` and `currency`: Use this combination for simulations that do not depend on specific CRM\ \ data.\n\n> \U0001F4D8 Required data\n> \n> You must provide either the `external_opportunity_id` or both the `geo_code`\ \ and `currency` parameters. Providing both in the same request will result in an error." operationId: simulateQuote requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SimulateQuoteRequest' examples: simulateQuoteExample: summary: Simulate a quote with playbook data and line items value: version_id: 20AFDC77E768B703 geo_code: us currency: USD line_item_details: all playbook: playbook_api total_sales_discount: 10 partner_program: - partner_level_name: Silver program_name: Program Name Silver 1 - partner_level_name: Gold program_name: Program Name Gold 1 - partner_level_name: Platinum program_name: Program Name Platinuml quote_data: - group_id: qg1 questions: - question_id_1: idl_val question_id_2: id2_vall;id2_val2;id2_val3 question_id_3: id3_val - question_id_1: idl_val question_id_2: id2_valA;valB;val2 question_id_3: id3_val - group_id: qg2 questions: - question_id_1: idl_val question_id_2: A;B;C question_id_3: some_val - question_id_1: idl_val question_id_2: A,D,N question_id_3: another_val line_items: - sku: product SKU item_name: Sweatpants list_price: 368 net_price_per_unit: 368 net_price: 1472 msrp: 0 msrp_discount: 0 sales_discount: 0 total_discount: 0 product_factors: Duration: 2 Quantity: 2 attributes: numeric PA: '50' currency PA: '50' responses: '200': description: Simulation successful. content: application/json: schema: $ref: '#/components/schemas/QuoteResponse' examples: simulateQuoteResponseExample: summary: Successful simulation response value: approval_flows: false summary: currency: USD total_list_price: 458154.42 total_net_price: 238042.66 total_discount: 48.04 total_sales_discount: 0 line_items: - id: 12345zWIwGV12347 sku: '999451' bundle_ref: null name: Gold Shield Pack list_price: 50.04 net_price: 22500.02 product_factors: Duration: '1.0' Quantity: '1.0' total_discount: 55 additional_data: primary_tag: PS msrp: 50000.04 msrp_discount: 55 user_price: 22.02 net_per_unit: 22.02 partner_discounts: - name: Program Name Silver 1 discount: 20 price: 47.6 - name: Program Name Gold 1 discount: 30 price: 59.5 sales_discount: 55 attributes: ARR: '22.02' Customer Discount: '49.07' Item Status: Active Inventory Category: DEFAULT Product Line: Professional Services '400': description: Bad Request. The request payload is invalid or missing required information. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/v1/quote/generate: post: tags: - Headless Quoting summary: Generate a Quote description: 'Creates an official quote record in DealHub, links it to a CRM opportunity, and initiates any required approval workflows based on your active CPQ version. This is an asynchronous endpoint. When you send a request, the API provides an immediate response to confirm that the quote generation process has started. The full processing, including data synchronization with your CRM, happens in the background.' operationId: generateQuote requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GenerateQuoteRequest' examples: generateQuoteExample: summary: Generate a new quote to be published value: request_action: publish external_opportunity_id: 006J7000003wYhD line_item_details: all playbook: playbook_api quote_name: quote name dealroom_publish_name: Dealroom publish name expiration_date: 1793788799000 document_type: DealRoom total_sales_discount: 15 timezone_offset: 0 partner_program: - partner_level_name: Silver program_name: Program Name Silver 1 - partner_level_name: Gold program_name: Program Name Gold 1 - partner_level_name: Platinum program_name: Program Name Platinum 1 quote_data: - group_id: qg1 questions: - question_id_1: idl_val question_id_2: id2_vall;id2_val2;id2_val3 question_id_3: id3_val - question_id_1: idl_val question_id_2: id2_valA;valB;val2 question_id_3: id3_val - group_id: qg2 questions: - question_id_1: idl_val question_id_2: A;B;C question_id_3: some_val - question_id_1: idl_val question_id_2: A,D,N question_id_3: another_val line_items: - sku: product SKU item_name: Sweatpants list_price: 368 net_price_per_unit: 368 net_price: 1472 msrp: 0 msrp_discount: 0 sales_discount: 0 total_discount: 0 product_factors: Duration: 2 Quantity: 2 attributes: numeric PA: '50' currency PA: '50' responses: '202': description: Accepted. The quote generation process has been initiated. content: application/json: schema: $ref: '#/components/schemas/QuoteResponse' examples: generateQuoteResponseExample: summary: Successful quote generation response value: status: publish dealhub_proposal_id: Q-12927 dealhub_quote_id: 12345zWIwGV12344 dealroom_url: https://dealroom.deahub.io/xxxxxxx approval_flows: true summary: currency: USD total_list_price: 458154.42 total_net_price: 238042.66 total_discount: 48.04 total_sales_discount: 0 line_items: - id: 12345zWIwGV12347 sku: '999451' bundle_ref: '' name: Gold Shield Pack list_price: 50.04 net_price: 22500.02 product_factors: duration: '1.0' quantity: '1.0' total_discount: 55 additional_data: primary_tag: PS msrp: 50000.04 msrp_discount: 55 user_price: 22.02 net_per_unit: 22.02 partner_discounts: [] sales_discount: 55 attributes: ARR: '22.02' Customer Discount: '49.07' Item Status: Active End Reseller Price: '-' Inventory Category: DEFAULT Product Line: Professional Services '400': description: Bad Request. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/v1/quote/{dealhub_quote_id}/submit: post: tags: - Headless Quoting summary: Submit a Quote description: Asynchronously submits an existing `Draft` quote for approval. operationId: submitQuote parameters: - name: dealhub_quote_id in: path required: true schema: type: string description: The unique identifier of the quote in DealHub. requestBody: content: application/json: schema: $ref: '#/components/schemas/ActionRequest' responses: '202': description: Accepted. The submit action has been initiated. content: application/json: schema: $ref: '#/components/schemas/QuoteResponse' '400': description: Bad Request. The quote is not in a submittable state. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/v1/quote/{dealhub_quote_id}/publish: post: tags: - Headless Quoting summary: Publish a Quote description: Asynchronously publishes an existing `Ready to be sent` quote to a DealRoom. operationId: publishQuote parameters: - name: dealhub_quote_id in: path required: true schema: type: string description: The unique identifier of the quote in DealHub. requestBody: content: application/json: schema: $ref: '#/components/schemas/ActionRequest' responses: '202': description: Accepted. The publish action has been initiated. content: application/json: schema: $ref: '#/components/schemas/QuoteResponse' '400': description: Bad Request. The quote is not in a publishable state. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/v1/quote/{dealhub_quote_id}/sign_externally: post: tags: - Headless Quoting summary: Sign a Quote Externally description: Asynchronously marks an existing quote as `Won`. The quote must be in a `Ready to be sent` or `Published` status. operationId: signQuoteExternally parameters: - name: dealhub_quote_id in: path required: true schema: type: string description: The unique identifier of the quote in DealHub. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SignActionRequest' responses: '202': description: Accepted. The sign externally action has been initiated. content: application/json: schema: $ref: '#/components/schemas/QuoteResponse' '400': description: Bad Request. The quote cannot be signed. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/v1/quote/id/{dealhub_proposal_id}: get: tags: - Headless Quoting summary: Get DealHub Quote ID description: Retrieves the `dealhub_quote_id` using the `dealhub_proposal_id` (the ID visible in the UI). operationId: getQuoteId parameters: - name: dealhub_proposal_id in: path required: true schema: type: string description: The unique identifier of the proposal in DealHub. responses: '200': description: Success. content: application/json: schema: type: object properties: dealhub_quote_id: type: string examples: getQuoteIdExample: summary: Successful response value: dealhub_quote_id: 12345zWIwGV12344 '400': description: Bad Request. The proposal ID does not exist. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/v1/quote/generate-1: post: tags: - Headless Quoting summary: Copy of Generate a Quote description: 'Creates an official quote record in DealHub, links it to a CRM opportunity, and initiates any required approval workflows based on your active CPQ version. This is an asynchronous endpoint. When you send a request, the API provides an immediate response to confirm that the quote generation process has started. The full processing, including data synchronization with your CRM, happens in the background.' operationId: generateQuote-1 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GenerateQuoteRequest' examples: generateQuoteExample: summary: Generate a new quote to be published value: request_action: publish external_opportunity_id: 006J7000003wYhD line_item_details: all playbook: playbook_api quote_name: quote name dealroom_publish_name: Dealroom publish name expiration_date: 1793788799000 document_type: DealRoom total_sales_discount: 15 timezone_offset: 0 partner_program: - partner_level_name: Silver program_name: Program Name Silver 1 - partner_level_name: Gold program_name: Program Name Gold 1 - partner_level_name: Platinum program_name: Program Name Platinum 1 quote_data: - group_id: qg1 questions: - question_id_1: idl_val question_id_2: id2_vall;id2_val2;id2_val3 question_id_3: id3_val - question_id_1: idl_val question_id_2: id2_valA;valB;val2 question_id_3: id3_val - group_id: qg2 questions: - question_id_1: idl_val question_id_2: A;B;C question_id_3: some_val - question_id_1: idl_val question_id_2: A,D,N question_id_3: another_val line_items: - sku: product SKU item_name: Sweatpants list_price: 368 net_price_per_unit: 368 net_price: 1472 msrp: 0 msrp_discount: 0 sales_discount: 0 total_discount: 0 product_factors: Duration: 2 Quantity: 2 attributes: numeric PA: '50' currency PA: '50' responses: '202': description: Accepted. The quote generation process has been initiated. content: application/json: schema: $ref: '#/components/schemas/QuoteResponse' examples: generateQuoteResponseExample: summary: Successful quote generation response value: status: publish dealhub_proposal_id: Q-12927 dealhub_quote_id: 12345zWIwGV12344 dealroom_url: https://dealroom.deahub.io/xxxxxxx approval_flows: true summary: currency: USD total_list_price: 458154.42 total_net_price: 238042.66 total_discount: 48.04 total_sales_discount: 0 line_items: - id: 12345zWIwGV12347 sku: '999451' bundle_ref: '' name: Gold Shield Pack list_price: 50.04 net_price: 22500.02 product_factors: duration: '1.0' quantity: '1.0' total_discount: 55 additional_data: primary_tag: PS msrp: 50000.04 msrp_discount: 55 user_price: 22.02 net_per_unit: 22.02 partner_discounts: [] sales_discount: 55 attributes: ARR: '22.02' Customer Discount: '49.07' Item Status: Active End Reseller Price: '-' Inventory Category: DEFAULT Product Line: Professional Services '400': description: Bad Request. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' components: securitySchemes: bearerAuth: type: http scheme: bearer description: A secret token generated by a CPQ administrator. schemas: QuoteData: type: object properties: group_id: type: string maxLength: 50 description: DealHub group ID. questions: type: array description: 'List of questions data including question ID and answer/s. The following answer types are supported: * **Text List:** Contains one or more case-sensitive values, restricted to predefined options. Supports single or multi-select (delimiter: `;`). * **Text Answer:** Captures the value exactly as provided in the request payload. * **Radio Button:** Single case-sensitive value from predefined radio button selections. * **Manual Item:** Valid SKU existing in the system. * **Numeric List:** One or more numeric values from the answer predefined list (delimiter: `;`). * **Numeric Answer/Range:** Single numeric value within a predefined range. * **Date:** Date in `yyyy-mm-dd` format.' items: type: object additionalProperties: oneOf: - type: string - type: number - type: boolean required: - group_id - questions LineItem: type: object properties: sku: type: string description: Unique product catalog identifier. It must exist in the DealHub product catalog. item_name: type: string maxLength: 400 description: Catalog product name. bundle_ref_sku: type: string description: The SKU of the bundle product to which this line item belongs. The value is required if the line item is a component of a bundle. The bundle SKU must exist in the DealHub catalog. This field should be empty for the bundle product itself. bundle_ref_id: type: integer description: The unique identifier for a bundle instance. This is required for all line items within a bundle and for the bundle's line item itself. It is used to differentiate between multiple instances of the same bundle in a single import. list_price: type: number description: List price of the line item. net_price_per_unit: type: number description: Net price per unit of the line item. net_price: type: number description: Total net price (net per unit x product factors). msrp: type: number description: line item MSRP (Manufacturer Suggested Retail Price). msrp_discount: type: number description: Discount applied to the MSRP. sales_discount: type: number description: Line item sales discount. total_discount: type: number description: Line item total discount. partner_program_data: type: array items: type: object properties: partner_program_name: type: string maxLength: 200 description: Partner program name. partner_level_item_price: type: number description: Item price after partner program level discount. partner_level_item_discount: type: number description: Discount applied to the partner program level. product_factors: type: object description: List of product-specific factors (e.g., quantity, duration). additionalProperties: type: integer attributes: type: object description: List of line-item-specific proposal attributes. additionalProperties: type: string required: - sku PartnerProgram: type: object properties: partner_level_name: type: string program_name: type: string SimulateQuoteRequest: type: object properties: version_id: type: string maxLength: 16 description: DealHub version ID. If not provided, the system will use the active version. external_opportunity_id: type: string maxLength: 50 description: CRM opportunity ID. geo_code: type: string maxLength: 200 description: Geographic code. currency: type: string maxLength: 3 description: Currency ISO code to evaluate rules. Immutable once created. line_item_details: type: string enum: - basic - all default: basic description: Determines the level of detail included in the response for line items. playbook: type: string maxLength: 50 description: The unique name of the playbook (not the display name). If not provided, the system uses the first API-type playbook. total_sales_discount: type: number description: Total discount for all line items. Overrides default line-item discounts if provided. partner_program: type: array items: $ref: '#/components/schemas/PartnerProgram' description: List of selected partner programs. quote_data: type: array items: $ref: '#/components/schemas/QuoteData' description: List of question group data, including questions and answers for repeatable/non-repeatable groups. default: [] example: [] line_items: type: array items: $ref: '#/components/schemas/LineItem' description: A list of line items along with their associated data. required: - quote_data GenerateQuoteRequest: type: object properties: external_opportunity_id: type: string maxLength: 50 description: CRM opportunity ID. request_action: type: string enum: - draft - submit - publish - sign_externally description: Specifies the action (draft, submit, publish, or sign). line_item_details: type: string enum: - basic - all default: basic description: Determines the level of detail included in the response for line items. playbook: type: string maxLength: 50 description: The unique name of the playbook (not the display name). If not provided, the system uses the first API-type playbook. quote_name: type: string maxLength: 250 description: Quote or proposal name. dealroom_publish_name: type: string maxLength: 250 description: DealRoom publish name. total_sales_discount: type: number description: Total discount for all line items. Overrides default line-item discounts if provided. expiration_date: type: integer format: int64 description: Quote expiration date as a Unix timestamp (milliseconds, GMT). document_type: type: string enum: - DealRoom - PDF - WORD - EXCEL description: Specifies document type (e.g., DealRoom, PDF, WORD). partner_program: type: array items: $ref: '#/components/schemas/PartnerProgram' description: List of selected partner programs. timezone_offset: type: number description: Timezone offset from GMT in hours. sign_externally_comment: type: string maxLength: 1000 description: Includes the necessary comments for external signing. It is required if `request_action` is `sign_externally`. quote_data: type: array items: $ref: '#/components/schemas/QuoteData' description: List of question group data, including questions and answers. default: [] example: [] line_items: type: array items: $ref: '#/components/schemas/LineItem' description: A list of line items and their associated data. The system only validates that the SKU for each item exists. All other provided details are accepted as-is, and any existing data for these line items will be overwritten. opportunity_data: $ref: '#/components/schemas/OpportunityData' description: Opportunity context required for CRM API tenants. Must be provided when the DealHub tenant uses the CRM API integration type. required: - external_opportunity_id - request_action - document_type - quote_data ActionRequest: type: object properties: line_item_details: type: string enum: - basic - all default: basic description: Specifies the level of detail to include in the response for line items. SignActionRequest: allOf: - $ref: '#/components/schemas/ActionRequest' - type: object properties: sign_externally_comment: type: string maxLength: 1000 description: Includes the necessary comments for external signing. required: - sign_externally_comment QuoteResponse: type: object properties: status: type: string dealhub_proposal_id: type: string dealhub_quote_id: type: string dealroom_url: type: string format: uri approval_flows: type: boolean summary: $ref: '#/components/schemas/ResponseSummary' line_items: type: array items: $ref: '#/components/schemas/ResponseLineItem' ResponseSummary: type: object properties: currency: type: string total_list_price: type: number total_net_price: type: number total_discount: type: number total_sales_discount: type: number ResponseLineItem: type: object properties: id: type: string sku: type: string bundle_ref: type: string name: type: string list_price: type: number net_price: type: number product_factors: type: object additionalProperties: type: string total_discount: type: number additional_data: $ref: '#/components/schemas/ResponseAdditionalData' ResponseAdditionalData: type: object properties: primary_tag: type: string msrp: type: number msrp_discount: type: number user_price: type: number net_per_unit: type: number partner_discounts: type: array items: type: object properties: name: type: string discount: type: number price: type: number sales_discount: type: number attributes: type: object additionalProperties: oneOf: - type: string - type: number OpportunityData: type: object description: Opportunity context required when the DealHub tenant uses the CRM API integration type. properties: external_opportunity_name: type: string maxLength: 200 description: The name of the CRM opportunity. opportunity_owner: $ref: '#/components/schemas/OpportunityOwner' external_customer_id: type: string maxLength: 50 description: CRM customer ID (buyer account). customer_name: type: string maxLength: 256 description: CRM customer name. geo_code: type: string maxLength: 100 description: Geographic code. currency: type: string maxLength: 3 description: Currency ISO code used for evaluating rules. This value is immutable once the opportunity or quote is created. customer_shipping_address: $ref: '#/components/schemas/CustomerAddress' description: Customer's shipping address. customer_billing_address: $ref: '#/components/schemas/CustomerAddress' description: Customer's billing address. customer_contacts: type: array items: $ref: '#/components/schemas/CustomerContact' description: List of customer contact details. required: - external_opportunity_name - opportunity_owner - external_customer_id - customer_name - geo_code - currency OpportunityOwner: type: object description: Information about the opportunity owner. properties: external_user_id: type: string maxLength: 200 description: The CRM user ID. Represents an employee of the organization integrating with DealHub. login: type: string maxLength: 100 description: The user's login identifier. If not provided, the system uses the email as the login. The login must be unique across all DealHub tenants. email: type: string maxLength: 100 description: The primary email address of the user. name: type: string maxLength: 300 description: The user's full name. position: type: string maxLength: 300 description: The user's role or job title within the organization. phone: type: string maxLength: 50 description: The user's phone number. mobile: type: string maxLength: 100 description: The user's mobile phone number. fax: type: string maxLength: 100 description: The user's fax number. company: type: string maxLength: 100 description: The name of the user's company. street: type: string maxLength: 128 description: The street address of the user. city: type: string maxLength: 32 description: The city where the user is located. state: type: string maxLength: 32 description: The state where the user is located. country: type: string maxLength: 32 description: The user's country. postal_code: type: string maxLength: 16 description: The postal code of the user's location. user_manager_login: type: string maxLength: 100 description: The login ID of the user's manager. required: - external_user_id - email - name CustomerAddress: type: object description: Address details for a customer. properties: street: type: string maxLength: 128 description: The street address. city: type: string maxLength: 32 description: The city. state: type: string maxLength: 32 description: The state. country: type: string maxLength: 32 description: The country. postal_code: type: string maxLength: 16 description: The postal code. CustomerContact: type: object description: Details about a customer contact person. properties: salutation: type: string maxLength: 50 description: Salutation for the contact (e.g., Mr., Ms.). first_name: type: string maxLength: 128 description: First name of the contact. last_name: type: string maxLength: 128 description: Last name of the contact. title: type: string maxLength: 400 description: Job title of the contact. email: type: string maxLength: 100 description: Primary email address of the contact. phone: type: string maxLength: 50 description: Phone number of the contact. account_name: type: string maxLength: 100 description: Name of the contact's company. mailing_address: type: string maxLength: 250 description: Postal address of the contact. primary_contact: type: boolean description: Whether this is the primary contact. required: - first_name - last_name - email ErrorResponse: type: object properties: error: type: string x-readme: explorer-enabled: true proxy-enabled: true