curl --request POST \
--url https://production-api.joinrings.com/v1/opportunities \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"stage_uuid": "<string>",
"type_uuid": "<string>",
"associations": [
{
"entity_type": "<string>",
"entity_uuid": "<string>",
"context": "<string>"
}
],
"close_date": "<string>",
"custom_fields": [
{
"uuid": "<string>",
"float_value": 123,
"string_value": "<string>"
}
],
"details": "<string>",
"intro_date": "<string>",
"intro_person_uuid": "<string>",
"next_step": "<string>",
"owner_user_uuid": "<string>",
"parent_uuid": "<string>",
"probability": 123,
"source_date": "<string>",
"value": 123
}
'import requests
url = "https://production-api.joinrings.com/v1/opportunities"
payload = {
"name": "<string>",
"stage_uuid": "<string>",
"type_uuid": "<string>",
"associations": [
{
"entity_type": "<string>",
"entity_uuid": "<string>",
"context": "<string>"
}
],
"close_date": "<string>",
"custom_fields": [
{
"uuid": "<string>",
"float_value": 123,
"string_value": "<string>"
}
],
"details": "<string>",
"intro_date": "<string>",
"intro_person_uuid": "<string>",
"next_step": "<string>",
"owner_user_uuid": "<string>",
"parent_uuid": "<string>",
"probability": 123,
"source_date": "<string>",
"value": 123
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
stage_uuid: '<string>',
type_uuid: '<string>',
associations: [{entity_type: '<string>', entity_uuid: '<string>', context: '<string>'}],
close_date: '<string>',
custom_fields: [{uuid: '<string>', float_value: 123, string_value: '<string>'}],
details: '<string>',
intro_date: '<string>',
intro_person_uuid: '<string>',
next_step: '<string>',
owner_user_uuid: '<string>',
parent_uuid: '<string>',
probability: 123,
source_date: '<string>',
value: 123
})
};
fetch('https://production-api.joinrings.com/v1/opportunities', 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://production-api.joinrings.com/v1/opportunities",
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([
'name' => '<string>',
'stage_uuid' => '<string>',
'type_uuid' => '<string>',
'associations' => [
[
'entity_type' => '<string>',
'entity_uuid' => '<string>',
'context' => '<string>'
]
],
'close_date' => '<string>',
'custom_fields' => [
[
'uuid' => '<string>',
'float_value' => 123,
'string_value' => '<string>'
]
],
'details' => '<string>',
'intro_date' => '<string>',
'intro_person_uuid' => '<string>',
'next_step' => '<string>',
'owner_user_uuid' => '<string>',
'parent_uuid' => '<string>',
'probability' => 123,
'source_date' => '<string>',
'value' => 123
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://production-api.joinrings.com/v1/opportunities"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"stage_uuid\": \"<string>\",\n \"type_uuid\": \"<string>\",\n \"associations\": [\n {\n \"entity_type\": \"<string>\",\n \"entity_uuid\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"close_date\": \"<string>\",\n \"custom_fields\": [\n {\n \"uuid\": \"<string>\",\n \"float_value\": 123,\n \"string_value\": \"<string>\"\n }\n ],\n \"details\": \"<string>\",\n \"intro_date\": \"<string>\",\n \"intro_person_uuid\": \"<string>\",\n \"next_step\": \"<string>\",\n \"owner_user_uuid\": \"<string>\",\n \"parent_uuid\": \"<string>\",\n \"probability\": 123,\n \"source_date\": \"<string>\",\n \"value\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://production-api.joinrings.com/v1/opportunities")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"stage_uuid\": \"<string>\",\n \"type_uuid\": \"<string>\",\n \"associations\": [\n {\n \"entity_type\": \"<string>\",\n \"entity_uuid\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"close_date\": \"<string>\",\n \"custom_fields\": [\n {\n \"uuid\": \"<string>\",\n \"float_value\": 123,\n \"string_value\": \"<string>\"\n }\n ],\n \"details\": \"<string>\",\n \"intro_date\": \"<string>\",\n \"intro_person_uuid\": \"<string>\",\n \"next_step\": \"<string>\",\n \"owner_user_uuid\": \"<string>\",\n \"parent_uuid\": \"<string>\",\n \"probability\": 123,\n \"source_date\": \"<string>\",\n \"value\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://production-api.joinrings.com/v1/opportunities")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"stage_uuid\": \"<string>\",\n \"type_uuid\": \"<string>\",\n \"associations\": [\n {\n \"entity_type\": \"<string>\",\n \"entity_uuid\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"close_date\": \"<string>\",\n \"custom_fields\": [\n {\n \"uuid\": \"<string>\",\n \"float_value\": 123,\n \"string_value\": \"<string>\"\n }\n ],\n \"details\": \"<string>\",\n \"intro_date\": \"<string>\",\n \"intro_person_uuid\": \"<string>\",\n \"next_step\": \"<string>\",\n \"owner_user_uuid\": \"<string>\",\n \"parent_uuid\": \"<string>\",\n \"probability\": 123,\n \"source_date\": \"<string>\",\n \"value\": 123\n}"
response = http.request(request)
puts response.read_body{
"uuid": "<string>",
"created_at": 123,
"updated_at": 123
}Create an opportunity
Required fields: name, type_uuid, stage_uuid. If the user hasn’t specified an opportunity type or stage, ask them before calling this endpoint.
To discover valid IDs, first call GET /v1/opportunity-types to choose a type_uuid (and inspect its pinning_config to learn whether a person/company association is required), then call GET /v1/opportunity-types//stages to choose a stage_uuid for that type. A stage_uuid is only valid for the type_uuid it belongs to.
Optional: details, value, probability, source_date, intro_date, close_date,
intro_person_uuid, owner_user_uuid, associations (to link persons/companies).
owner_user_uuid takes a user uuid from GET /v1/users; the person uuid an
existing opportunity reports under owner is accepted too. Defaults to the
calling user. An owner that resolves to neither returns 400.
Returns the new opportunity UUID and timestamps on success (201).
curl --request POST \
--url https://production-api.joinrings.com/v1/opportunities \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"stage_uuid": "<string>",
"type_uuid": "<string>",
"associations": [
{
"entity_type": "<string>",
"entity_uuid": "<string>",
"context": "<string>"
}
],
"close_date": "<string>",
"custom_fields": [
{
"uuid": "<string>",
"float_value": 123,
"string_value": "<string>"
}
],
"details": "<string>",
"intro_date": "<string>",
"intro_person_uuid": "<string>",
"next_step": "<string>",
"owner_user_uuid": "<string>",
"parent_uuid": "<string>",
"probability": 123,
"source_date": "<string>",
"value": 123
}
'import requests
url = "https://production-api.joinrings.com/v1/opportunities"
payload = {
"name": "<string>",
"stage_uuid": "<string>",
"type_uuid": "<string>",
"associations": [
{
"entity_type": "<string>",
"entity_uuid": "<string>",
"context": "<string>"
}
],
"close_date": "<string>",
"custom_fields": [
{
"uuid": "<string>",
"float_value": 123,
"string_value": "<string>"
}
],
"details": "<string>",
"intro_date": "<string>",
"intro_person_uuid": "<string>",
"next_step": "<string>",
"owner_user_uuid": "<string>",
"parent_uuid": "<string>",
"probability": 123,
"source_date": "<string>",
"value": 123
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
stage_uuid: '<string>',
type_uuid: '<string>',
associations: [{entity_type: '<string>', entity_uuid: '<string>', context: '<string>'}],
close_date: '<string>',
custom_fields: [{uuid: '<string>', float_value: 123, string_value: '<string>'}],
details: '<string>',
intro_date: '<string>',
intro_person_uuid: '<string>',
next_step: '<string>',
owner_user_uuid: '<string>',
parent_uuid: '<string>',
probability: 123,
source_date: '<string>',
value: 123
})
};
fetch('https://production-api.joinrings.com/v1/opportunities', 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://production-api.joinrings.com/v1/opportunities",
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([
'name' => '<string>',
'stage_uuid' => '<string>',
'type_uuid' => '<string>',
'associations' => [
[
'entity_type' => '<string>',
'entity_uuid' => '<string>',
'context' => '<string>'
]
],
'close_date' => '<string>',
'custom_fields' => [
[
'uuid' => '<string>',
'float_value' => 123,
'string_value' => '<string>'
]
],
'details' => '<string>',
'intro_date' => '<string>',
'intro_person_uuid' => '<string>',
'next_step' => '<string>',
'owner_user_uuid' => '<string>',
'parent_uuid' => '<string>',
'probability' => 123,
'source_date' => '<string>',
'value' => 123
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://production-api.joinrings.com/v1/opportunities"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"stage_uuid\": \"<string>\",\n \"type_uuid\": \"<string>\",\n \"associations\": [\n {\n \"entity_type\": \"<string>\",\n \"entity_uuid\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"close_date\": \"<string>\",\n \"custom_fields\": [\n {\n \"uuid\": \"<string>\",\n \"float_value\": 123,\n \"string_value\": \"<string>\"\n }\n ],\n \"details\": \"<string>\",\n \"intro_date\": \"<string>\",\n \"intro_person_uuid\": \"<string>\",\n \"next_step\": \"<string>\",\n \"owner_user_uuid\": \"<string>\",\n \"parent_uuid\": \"<string>\",\n \"probability\": 123,\n \"source_date\": \"<string>\",\n \"value\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://production-api.joinrings.com/v1/opportunities")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"stage_uuid\": \"<string>\",\n \"type_uuid\": \"<string>\",\n \"associations\": [\n {\n \"entity_type\": \"<string>\",\n \"entity_uuid\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"close_date\": \"<string>\",\n \"custom_fields\": [\n {\n \"uuid\": \"<string>\",\n \"float_value\": 123,\n \"string_value\": \"<string>\"\n }\n ],\n \"details\": \"<string>\",\n \"intro_date\": \"<string>\",\n \"intro_person_uuid\": \"<string>\",\n \"next_step\": \"<string>\",\n \"owner_user_uuid\": \"<string>\",\n \"parent_uuid\": \"<string>\",\n \"probability\": 123,\n \"source_date\": \"<string>\",\n \"value\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://production-api.joinrings.com/v1/opportunities")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"stage_uuid\": \"<string>\",\n \"type_uuid\": \"<string>\",\n \"associations\": [\n {\n \"entity_type\": \"<string>\",\n \"entity_uuid\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"close_date\": \"<string>\",\n \"custom_fields\": [\n {\n \"uuid\": \"<string>\",\n \"float_value\": 123,\n \"string_value\": \"<string>\"\n }\n ],\n \"details\": \"<string>\",\n \"intro_date\": \"<string>\",\n \"intro_person_uuid\": \"<string>\",\n \"next_step\": \"<string>\",\n \"owner_user_uuid\": \"<string>\",\n \"parent_uuid\": \"<string>\",\n \"probability\": 123,\n \"source_date\": \"<string>\",\n \"value\": 123\n}"
response = http.request(request)
puts response.read_body{
"uuid": "<string>",
"created_at": 123,
"updated_at": 123
}Authorizations
Body
Show child attributes
Show child attributes
ISO 8601 date, e.g. '2026-08-07'. An ISO 8601 datetime is accepted and truncated to its date. Any other format is rejected with 400 -- these columns are dates, so locale-shaped values like '08/07/2026' are ambiguous and partial values like '2026-08' are not dates at all.
Show child attributes
Show child attributes
ISO 8601 date, e.g. '2026-08-07'. An ISO 8601 datetime is accepted and truncated to its date. Any other format is rejected with 400 -- these columns are dates, so locale-shaped values like '08/07/2026' are ambiguous and partial values like '2026-08' are not dates at all.
User UUID of the opportunity owner, as returned by GET /v1/users. The person UUID reported under owner on opportunity reads is accepted too, since that is what the record actually stores. A value matching neither is rejected with 400.
ISO 8601 date, e.g. '2026-08-07'. An ISO 8601 datetime is accepted and truncated to its date. Any other format is rejected with 400 -- these columns are dates, so locale-shaped values like '08/07/2026' are ambiguous and partial values like '2026-08' are not dates at all.