Create a draft Quote
Creates DRAFT Quotes only. Requires Idempotency-Key. Validates accessible Customer/Property/Opportunity, active Quote Type/Template, owner defaults, placed custom Fields, External References, audit, and domain events. ownerId is create-only in v1; generic Quote PATCH cannot reassign ownership. Without originatorId, the Quote takes its Opportunity's Originator, or credits its owner when it has no Opportunity. An answer in customFields to a Property Field (see isPropertyField) becomes the Property's answer, is recorded in its history, and fills that Field on the Property's draft Quotes and open Projects where it is still blank; a Quote Template's default is not an answer. Required scope: quotes:write.
Creates DRAFT Quotes only. Requires Idempotency-Key. Validates accessible Customer/Property/Opportunity, active Quote Type/Template, owner defaults, placed custom Fields, External References, audit, and domain events. ownerId is create-only in v1; generic Quote PATCH cannot reassign ownership. Without originatorId, the Quote takes its Opportunity's Originator, or credits its owner when it has no Opportunity. An answer in customFields to a Property Field (see isPropertyField) becomes the Property's answer, is recorded in its history, and fills that Field on the Property's draft Quotes and open Projects where it is still blank; a Quote Template's default is not an answer. Required scope: quotes:write.
Create a draft Quote. Use an organization API key with quotes:write. Check the response envelope and meta.requestId before triggering dependent workflow steps.
Required scopes
Parameters
No path or query parameters.
Request body
| Field | Type | Description |
|---|---|---|
| namerequired | string | Optional unless marked required. |
| customerIdrequired | string | Optional unless marked required. |
| propertyId | string | null | Optional unless marked required. |
| opportunityId | string | null | Optional unless marked required. |
| quoteTypeIdrequired | string | Optional unless marked required. |
| quoteTemplateId | string | null | Optional unless marked required. |
| validUntil | string | null | Optional unless marked required. |
| summary | string | null | Optional unless marked required. |
| notes | string | null | Optional unless marked required. |
| terms | string | null | Optional unless marked required. |
| ownerId | string | null | Active or draft same-organization Team Member id. When omitted, the API key default owner for this resource is used. Ownership cannot be changed through generic PATCH endpoints. |
| originatorId | string | null | The active or draft same-organization Team Member credited with bringing this sale in. When omitted, the Quote takes its Opportunity's Originator, or credits its owner when it has no Opportunity. |
| customFields | object | Field Values keyed by savedIdentity from GET /api/v1/schema. |
| externalReferences[] | array<object> | Optional unless marked required. |
| externalReferences[].externalSystemrequired | string | Optional unless marked required. |
| externalReferences[].externalObjectrequired | string | Optional unless marked required. |
| externalReferences[].externalIdrequired | string | Optional unless marked required. |
| externalReferences[].metadata | object | Optional unless marked required. |
{
"customerId": "customer_123",
"propertyId": "property_123",
"opportunityId": "opportunity_123",
"quoteTypeId": "quote_type_123",
"quoteTemplateId": "quote_template_123",
"name": "8.4 kW solar proposal"
}Responses
Created Quote envelope
#/components/schemas/OrgApiResourceEnvelope
Validation, owner, or custom Field error
#/components/schemas/OrgApiError
Missing or invalid organization API key
#/components/schemas/OrgApiError
Organization billing access or an endpoint-specific business quota denied the request
#/components/schemas/OrgApiError
Missing required scope: quotes:write
#/components/schemas/OrgApiError
Idempotency or External Reference conflict
#/components/schemas/OrgApiError
Rate limit exceeded
#/components/schemas/OrgApiError
Errors
Static examples
curl -X POST "$SOLAROS_BASE_URL/api/v1/quotes" \
-H "Authorization: Bearer $SOLAROS_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $SOLAROS_IDEMPOTENCY_KEY" \
--data '{"customerId":"customer_123","propertyId":"property_123","opportunityId":"opportunity_123","quoteTypeId":"quote_type_123","quoteTemplateId":"quote_template_123","name":"8.4 kW solar proposal"}'