Associate an Opportunity with a Deal
curl --request POST \
--url https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_deal \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"deal": {
"id": "deal_d1ce34c57bfefff7"
}
}
'import requests
url = "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_deal"
payload = { "deal": { "id": "deal_d1ce34c57bfefff7" } }
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({deal: {id: 'deal_d1ce34c57bfefff7'}})
};
fetch('https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_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}/associate_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([
'deal' => [
'id' => 'deal_d1ce34c57bfefff7'
]
]),
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}/associate_deal"
payload := strings.NewReader("{\n \"deal\": {\n \"id\": \"deal_d1ce34c57bfefff7\"\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}/associate_deal")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"deal\": {\n \"id\": \"deal_d1ce34c57bfefff7\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_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 \"deal\": {\n \"id\": \"deal_d1ce34c57bfefff7\"\n }\n}"
response = http.request(request)
puts response.read_body{
"opportunity": {
"id": "opp_127b3057d5df338e",
"archived_at": null,
"associated_at": "2025-02-22T14:41:00Z",
"contact": {
"id": "con_1234567890abcdef"
},
"created_at": "2025-02-22T14:41:00Z",
"creator": {
"id": "tok_7f6e5fb4bb548dbc"
},
"deal": {
"id": "deal_d1ce34c57bfefff7"
},
"line_items": [],
"metadata": {},
"site": {
"id": "site_14b419f1096013f1"
},
"source": "public_api",
"status": "associated",
"updated_at": "2025-02-22T14:41:00Z"
},
"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 Deal 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: deal",
"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"
}
}Opportunities
Associate an Opportunity with a Deal
Associate an opportunity with an existing deal. A deal can be associated with several opportunities, but an opportunity with only one deal. The deal and the opportunity must belong to the same contact.
Associating an archived opportunity unarchives it. The deal itself is not changed.
Returns 409 Conflict when the opportunity is already associated with a deal, was converted to a deal before, or belongs to a different contact than the deal.
Required authorization scopes: public.opportunity:write, public.deal:write
POST
/
2025-09
/
opportunities
/
{opportunity_id}
/
associate_deal
Associate an Opportunity with a Deal
curl --request POST \
--url https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_deal \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"deal": {
"id": "deal_d1ce34c57bfefff7"
}
}
'import requests
url = "https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_deal"
payload = { "deal": { "id": "deal_d1ce34c57bfefff7" } }
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({deal: {id: 'deal_d1ce34c57bfefff7'}})
};
fetch('https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_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}/associate_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([
'deal' => [
'id' => 'deal_d1ce34c57bfefff7'
]
]),
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}/associate_deal"
payload := strings.NewReader("{\n \"deal\": {\n \"id\": \"deal_d1ce34c57bfefff7\"\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}/associate_deal")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"deal\": {\n \"id\": \"deal_d1ce34c57bfefff7\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.stora.co/2025-09/opportunities/{opportunity_id}/associate_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 \"deal\": {\n \"id\": \"deal_d1ce34c57bfefff7\"\n }\n}"
response = http.request(request)
puts response.read_body{
"opportunity": {
"id": "opp_127b3057d5df338e",
"archived_at": null,
"associated_at": "2025-02-22T14:41:00Z",
"contact": {
"id": "con_1234567890abcdef"
},
"created_at": "2025-02-22T14:41:00Z",
"creator": {
"id": "tok_7f6e5fb4bb548dbc"
},
"deal": {
"id": "deal_d1ce34c57bfefff7"
},
"line_items": [],
"metadata": {},
"site": {
"id": "site_14b419f1096013f1"
},
"source": "public_api",
"status": "associated",
"updated_at": "2025-02-22T14:41:00Z"
},
"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 Deal 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: deal",
"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
BearerOAuth2
Bearer Token necessary to use API
Path Parameters
The ID of the opportunity
Pattern:
^opp_Query Parameters
This endpoint supports expandable responses. For more, see the documentation page.
Body
application/json
Associate Opportunity with Deal Request
Show child attributes
Show child attributes
Was this page helpful?