curl --request POST \
--url https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"stage": {
"id": "dstg_127b3057d5df338e"
},
"name": "Jane Doe Storage",
"assignee": {
"id": "staff_947b3057d5df338e"
},
"note": "Around 100 a month",
"metadata": {
"source": "zapier"
}
}
'import requests
url = "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal"
payload = {
"stage": { "id": "dstg_127b3057d5df338e" },
"name": "Jane Doe Storage",
"assignee": { "id": "staff_947b3057d5df338e" },
"note": "Around 100 a month",
"metadata": { "source": "zapier" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
stage: {id: 'dstg_127b3057d5df338e'},
name: 'Jane Doe Storage',
assignee: {id: 'staff_947b3057d5df338e'},
note: 'Around 100 a month',
metadata: {source: 'zapier'}
})
};
fetch('https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'stage' => [
'id' => 'dstg_127b3057d5df338e'
],
'name' => 'Jane Doe Storage',
'assignee' => [
'id' => 'staff_947b3057d5df338e'
],
'note' => 'Around 100 a month',
'metadata' => [
'source' => 'zapier'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal"
payload := strings.NewReader("{\n \"stage\": {\n \"id\": \"dstg_127b3057d5df338e\"\n },\n \"name\": \"Jane Doe Storage\",\n \"assignee\": {\n \"id\": \"staff_947b3057d5df338e\"\n },\n \"note\": \"Around 100 a month\",\n \"metadata\": {\n \"source\": \"zapier\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"stage\": {\n \"id\": \"dstg_127b3057d5df338e\"\n },\n \"name\": \"Jane Doe Storage\",\n \"assignee\": {\n \"id\": \"staff_947b3057d5df338e\"\n },\n \"note\": \"Around 100 a month\",\n \"metadata\": {\n \"source\": \"zapier\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"stage\": {\n \"id\": \"dstg_127b3057d5df338e\"\n },\n \"name\": \"Jane Doe Storage\",\n \"assignee\": {\n \"id\": \"staff_947b3057d5df338e\"\n },\n \"note\": \"Around 100 a month\",\n \"metadata\": {\n \"source\": \"zapier\"\n }\n}"
response = http.request(request)
puts response.read_body{
"deal": {
"id": "deal_d1ce34c57bfefff7",
"assignee": {
"id": "staff_947b3057d5df338e"
},
"contact": {
"id": "con_1234567890abcdef"
},
"created_at": "2025-02-22T14:41:00Z",
"creator": {
"id": "app_99b90b9d208a137b"
},
"line_items": [
{
"item": {
"id": "plvl_e8f3ad0a07e47566"
},
"quantity": 1,
"type": "protection"
},
{
"item": {
"id": "utype_f18fc91387cdf710"
},
"quantity": 1,
"type": "unit_type"
}
],
"lost_reason": null,
"metadata": {
"source": "zapier"
},
"name": "Jane Doe Storage",
"note": "Around 100 a month",
"site": {
"id": "site_14b419f1096013f1"
},
"stage": {
"id": "dstg_127b3057d5df338e"
},
"starts_at": null,
"status": "open",
"updated_at": "2025-02-22T14:41:00Z",
"value_estimate": "Around 100 a month"
},
"meta": {
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"curies": [
{
"name": "bo",
"href": "https://app.stora.test{rel}",
"templated": true,
"title": "Backoffice"
},
{
"name": "sf",
"href": "https://acme.stora.test{rel}",
"templated": true,
"title": "Storefront"
}
]
}
}{
"error": {
"code": "resource_not_found",
"details": [],
"links": [
{
"kind": "open_api",
"name": "OpenAPI specification",
"url": "https://docs.stora.test/2025-09/openapi.json"
},
{
"kind": "documentation",
"name": "Errors",
"url": "https://docs.stora.test/2025-09/guides/errors"
}
],
"message": "The Opportunity was not found.",
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"type": "invalid_request_error"
}
}{
"error": {
"code": "opportunity_associated",
"details": [],
"links": [
{
"kind": "open_api",
"name": "OpenAPI specification",
"url": "https://docs.stora.test/2025-09/openapi.json"
},
{
"kind": "documentation",
"name": "Errors",
"url": "https://docs.stora.test/2025-09/guides/errors"
}
],
"message": "The opportunity is already associated with a deal.",
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"type": "invalid_request_error"
}
}{
"error": {
"code": "invalid_content",
"details": [
{
"message": "object at root is missing required properties: stage",
"pointer": null
}
],
"links": [
{
"kind": "open_api",
"name": "OpenAPI specification",
"url": "https://docs.stora.test/2025-09/openapi.json"
},
{
"kind": "documentation",
"name": "Errors",
"url": "https://docs.stora.test/2025-09/guides/errors"
}
],
"message": "The request body content is not valid.",
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"type": "invalid_request_error"
}
}Create a Deal from an Opportunity
Create a deal from an opportunity and associate them. The deal takes the opportunity’s contact, site and line items, and is placed on the deals board at the specified stage.
An opportunity can only be converted once. Converting an archived opportunity unarchives it.
Returns 409 Conflict when the opportunity is already associated with a deal, was converted before, or has a unit type or protection level that does not belong to its site.
Required authorization scopes: public.opportunity:write, public.deal:write
curl --request POST \
--url https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"stage": {
"id": "dstg_127b3057d5df338e"
},
"name": "Jane Doe Storage",
"assignee": {
"id": "staff_947b3057d5df338e"
},
"note": "Around 100 a month",
"metadata": {
"source": "zapier"
}
}
'import requests
url = "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal"
payload = {
"stage": { "id": "dstg_127b3057d5df338e" },
"name": "Jane Doe Storage",
"assignee": { "id": "staff_947b3057d5df338e" },
"note": "Around 100 a month",
"metadata": { "source": "zapier" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
stage: {id: 'dstg_127b3057d5df338e'},
name: 'Jane Doe Storage',
assignee: {id: 'staff_947b3057d5df338e'},
note: 'Around 100 a month',
metadata: {source: 'zapier'}
})
};
fetch('https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'stage' => [
'id' => 'dstg_127b3057d5df338e'
],
'name' => 'Jane Doe Storage',
'assignee' => [
'id' => 'staff_947b3057d5df338e'
],
'note' => 'Around 100 a month',
'metadata' => [
'source' => 'zapier'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal"
payload := strings.NewReader("{\n \"stage\": {\n \"id\": \"dstg_127b3057d5df338e\"\n },\n \"name\": \"Jane Doe Storage\",\n \"assignee\": {\n \"id\": \"staff_947b3057d5df338e\"\n },\n \"note\": \"Around 100 a month\",\n \"metadata\": {\n \"source\": \"zapier\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"stage\": {\n \"id\": \"dstg_127b3057d5df338e\"\n },\n \"name\": \"Jane Doe Storage\",\n \"assignee\": {\n \"id\": \"staff_947b3057d5df338e\"\n },\n \"note\": \"Around 100 a month\",\n \"metadata\": {\n \"source\": \"zapier\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/deal")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"stage\": {\n \"id\": \"dstg_127b3057d5df338e\"\n },\n \"name\": \"Jane Doe Storage\",\n \"assignee\": {\n \"id\": \"staff_947b3057d5df338e\"\n },\n \"note\": \"Around 100 a month\",\n \"metadata\": {\n \"source\": \"zapier\"\n }\n}"
response = http.request(request)
puts response.read_body{
"deal": {
"id": "deal_d1ce34c57bfefff7",
"assignee": {
"id": "staff_947b3057d5df338e"
},
"contact": {
"id": "con_1234567890abcdef"
},
"created_at": "2025-02-22T14:41:00Z",
"creator": {
"id": "app_99b90b9d208a137b"
},
"line_items": [
{
"item": {
"id": "plvl_e8f3ad0a07e47566"
},
"quantity": 1,
"type": "protection"
},
{
"item": {
"id": "utype_f18fc91387cdf710"
},
"quantity": 1,
"type": "unit_type"
}
],
"lost_reason": null,
"metadata": {
"source": "zapier"
},
"name": "Jane Doe Storage",
"note": "Around 100 a month",
"site": {
"id": "site_14b419f1096013f1"
},
"stage": {
"id": "dstg_127b3057d5df338e"
},
"starts_at": null,
"status": "open",
"updated_at": "2025-02-22T14:41:00Z",
"value_estimate": "Around 100 a month"
},
"meta": {
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"curies": [
{
"name": "bo",
"href": "https://app.stora.test{rel}",
"templated": true,
"title": "Backoffice"
},
{
"name": "sf",
"href": "https://acme.stora.test{rel}",
"templated": true,
"title": "Storefront"
}
]
}
}{
"error": {
"code": "resource_not_found",
"details": [],
"links": [
{
"kind": "open_api",
"name": "OpenAPI specification",
"url": "https://docs.stora.test/2025-09/openapi.json"
},
{
"kind": "documentation",
"name": "Errors",
"url": "https://docs.stora.test/2025-09/guides/errors"
}
],
"message": "The Opportunity was not found.",
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"type": "invalid_request_error"
}
}{
"error": {
"code": "opportunity_associated",
"details": [],
"links": [
{
"kind": "open_api",
"name": "OpenAPI specification",
"url": "https://docs.stora.test/2025-09/openapi.json"
},
{
"kind": "documentation",
"name": "Errors",
"url": "https://docs.stora.test/2025-09/guides/errors"
}
],
"message": "The opportunity is already associated with a deal.",
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"type": "invalid_request_error"
}
}{
"error": {
"code": "invalid_content",
"details": [
{
"message": "object at root is missing required properties: stage",
"pointer": null
}
],
"links": [
{
"kind": "open_api",
"name": "OpenAPI specification",
"url": "https://docs.stora.test/2025-09/openapi.json"
},
{
"kind": "documentation",
"name": "Errors",
"url": "https://docs.stora.test/2025-09/guides/errors"
}
],
"message": "The request body content is not valid.",
"request_id": "01563646-58c1-4607-8fe0-cae3e92c4477",
"type": "invalid_request_error"
}
}Authorizations
Bearer Token necessary to use API
Path Parameters
The ID of the opportunity to create the deal from
^opp_Query Parameters
This endpoint supports expandable responses. For more, see the documentation page.
Body
Create Deal from Opportunity Request
Show child attributes
Show child attributes
The name of the deal. Defaults to the contact's name, or email if the contact has no name, followed by "Deal".
Show child attributes
Show child attributes
Free-text note for the deal. Displayed under 'Deal value estimate' in Backoffice.
Set of key-value pairs for storing additional information on the deal. Learn more about metadata.
Show child attributes
Show child attributes
Was this page helpful?