curl --request POST \
--url https://api.openpulse.cloud/v1/pipeline/bulk \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"signalIds": [
"<string>"
],
"stage": "new",
"ownerUserId": "<string>"
}
'import requests
url = "https://api.openpulse.cloud/v1/pipeline/bulk"
payload = {
"signalIds": ["<string>"],
"stage": "new",
"ownerUserId": "<string>"
}
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({signalIds: ['<string>'], stage: 'new', ownerUserId: '<string>'})
};
fetch('https://api.openpulse.cloud/v1/pipeline/bulk', 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://api.openpulse.cloud/v1/pipeline/bulk",
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([
'signalIds' => [
'<string>'
],
'stage' => 'new',
'ownerUserId' => '<string>'
]),
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://api.openpulse.cloud/v1/pipeline/bulk"
payload := strings.NewReader("{\n \"signalIds\": [\n \"<string>\"\n ],\n \"stage\": \"new\",\n \"ownerUserId\": \"<string>\"\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://api.openpulse.cloud/v1/pipeline/bulk")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"signalIds\": [\n \"<string>\"\n ],\n \"stage\": \"new\",\n \"ownerUserId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.openpulse.cloud/v1/pipeline/bulk")
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 \"signalIds\": [\n \"<string>\"\n ],\n \"stage\": \"new\",\n \"ownerUserId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"added": 123,
"duplicate": 123,
"missing": 123
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}{
"message": "<string>",
"code": "plan_required",
"plan": "op_go"
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}Add several deals at once
One request rather than a loop, which is what an agent working from a list of signals should reach for.
Partial success is the expected outcome and answers 200. A selection made from a table routinely contains signals already on the board, so the response counts what happened to each group rather than failing the batch over a duplicate. Nothing here is transactional and nothing needs to be: every insert is independent, and the unique index makes a repeated request converge rather than accumulate.
curl --request POST \
--url https://api.openpulse.cloud/v1/pipeline/bulk \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"signalIds": [
"<string>"
],
"stage": "new",
"ownerUserId": "<string>"
}
'import requests
url = "https://api.openpulse.cloud/v1/pipeline/bulk"
payload = {
"signalIds": ["<string>"],
"stage": "new",
"ownerUserId": "<string>"
}
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({signalIds: ['<string>'], stage: 'new', ownerUserId: '<string>'})
};
fetch('https://api.openpulse.cloud/v1/pipeline/bulk', 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://api.openpulse.cloud/v1/pipeline/bulk",
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([
'signalIds' => [
'<string>'
],
'stage' => 'new',
'ownerUserId' => '<string>'
]),
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://api.openpulse.cloud/v1/pipeline/bulk"
payload := strings.NewReader("{\n \"signalIds\": [\n \"<string>\"\n ],\n \"stage\": \"new\",\n \"ownerUserId\": \"<string>\"\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://api.openpulse.cloud/v1/pipeline/bulk")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"signalIds\": [\n \"<string>\"\n ],\n \"stage\": \"new\",\n \"ownerUserId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.openpulse.cloud/v1/pipeline/bulk")
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 \"signalIds\": [\n \"<string>\"\n ],\n \"stage\": \"new\",\n \"ownerUserId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"added": 123,
"duplicate": 123,
"missing": 123
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}{
"message": "<string>",
"code": "plan_required",
"plan": "op_go"
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}{
"message": "<string>",
"code": "<string>",
"detail": "<unknown>"
}Authorizations
A workspace API key, created in workspace settings and sent as Authorization: Bearer op_live_…. Session cookies are not accepted. Scopes: signals:read, accounts:read, listeners:read, listeners:analyse, pipeline:read, pipeline:write, collections:write, export:read.
Body
The signals to open deals from. Duplicates in the list are collapsed first.
Up to 200. The cap is a backstop rather than a limit anyone meets: past a couple of hundred this stops being an action somebody took and starts being an import, which wants a job and a progress bar instead.
1 - 200 elementsA signal id.
1 - 120Where every created deal lands.
new, contacted, meeting, won, lost Clerk user id to assign every created deal to.
120Response
What happened, per group. The three counts sum to the deduplicated id count.
What a bulk add did, reported per group rather than as one total. Partial success is the expected outcome, not an error: a selection made from a table will routinely contain signals already on the board.
Deals created.
Already on the board. The ordinary case for a re-selected row.
Ids that named no signal in this workspace. Reported rather than swallowed: it is the difference between "already on your board" and "those ids do not exist here".
Was this page helpful?