curl --request POST \
--url https://app.sideshift.app/api/oauth/v1/discover/leads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"listingId": "<string>",
"agencyCompanyId": "<string>",
"name": "<string>",
"email": "<string>",
"phone": "<string>",
"customAnswers": {}
}
'import requests
url = "https://app.sideshift.app/api/oauth/v1/discover/leads"
payload = {
"listingId": "<string>",
"agencyCompanyId": "<string>",
"name": "<string>",
"email": "<string>",
"phone": "<string>",
"customAnswers": {}
}
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({
listingId: '<string>',
agencyCompanyId: '<string>',
name: '<string>',
email: '<string>',
phone: '<string>',
customAnswers: {}
})
};
fetch('https://app.sideshift.app/api/oauth/v1/discover/leads', 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://app.sideshift.app/api/oauth/v1/discover/leads",
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([
'listingId' => '<string>',
'agencyCompanyId' => '<string>',
'name' => '<string>',
'email' => '<string>',
'phone' => '<string>',
'customAnswers' => [
]
]),
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://app.sideshift.app/api/oauth/v1/discover/leads"
payload := strings.NewReader("{\n \"listingId\": \"<string>\",\n \"agencyCompanyId\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"customAnswers\": {}\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://app.sideshift.app/api/oauth/v1/discover/leads")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"listingId\": \"<string>\",\n \"agencyCompanyId\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"customAnswers\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sideshift.app/api/oauth/v1/discover/leads")
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 \"listingId\": \"<string>\",\n \"agencyCompanyId\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"customAnswers\": {}\n}"
response = http.request(request)
puts response.read_body{
"data": {
"success": true,
"submissionId": "<string>",
"supportChannelId": "<string>",
"externalMessageId": "<string>",
"messageDelivered": true,
"authRequired": true,
"messageDeliveryError": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing bearer access token",
"requestId": "req_..."
}
}{
"error": {
"code": "insufficient_scope",
"message": "Requires scope 'campaigns:write'",
"requestId": "req_..."
}
}{
"error": {
"code": "not_found",
"message": "Resource not found",
"requestId": "req_..."
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded",
"requestId": "req_..."
}
}Submit a Discover lead
Submit a qualified Discover lead-form submission for the token tenant (the agency-side inbox). Requires the discover:write scope.
curl --request POST \
--url https://app.sideshift.app/api/oauth/v1/discover/leads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"listingId": "<string>",
"agencyCompanyId": "<string>",
"name": "<string>",
"email": "<string>",
"phone": "<string>",
"customAnswers": {}
}
'import requests
url = "https://app.sideshift.app/api/oauth/v1/discover/leads"
payload = {
"listingId": "<string>",
"agencyCompanyId": "<string>",
"name": "<string>",
"email": "<string>",
"phone": "<string>",
"customAnswers": {}
}
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({
listingId: '<string>',
agencyCompanyId: '<string>',
name: '<string>',
email: '<string>',
phone: '<string>',
customAnswers: {}
})
};
fetch('https://app.sideshift.app/api/oauth/v1/discover/leads', 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://app.sideshift.app/api/oauth/v1/discover/leads",
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([
'listingId' => '<string>',
'agencyCompanyId' => '<string>',
'name' => '<string>',
'email' => '<string>',
'phone' => '<string>',
'customAnswers' => [
]
]),
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://app.sideshift.app/api/oauth/v1/discover/leads"
payload := strings.NewReader("{\n \"listingId\": \"<string>\",\n \"agencyCompanyId\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"customAnswers\": {}\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://app.sideshift.app/api/oauth/v1/discover/leads")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"listingId\": \"<string>\",\n \"agencyCompanyId\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"customAnswers\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sideshift.app/api/oauth/v1/discover/leads")
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 \"listingId\": \"<string>\",\n \"agencyCompanyId\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"phone\": \"<string>\",\n \"customAnswers\": {}\n}"
response = http.request(request)
puts response.read_body{
"data": {
"success": true,
"submissionId": "<string>",
"supportChannelId": "<string>",
"externalMessageId": "<string>",
"messageDelivered": true,
"authRequired": true,
"messageDeliveryError": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing bearer access token",
"requestId": "req_..."
}
}{
"error": {
"code": "insufficient_scope",
"message": "Requires scope 'campaigns:write'",
"requestId": "req_..."
}
}{
"error": {
"code": "not_found",
"message": "Resource not found",
"requestId": "req_..."
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded",
"requestId": "req_..."
}
}Authorizations
OAuth 2.1 authorization code + PKCE (S256). Tokens are tenant-bound (company_id) and scoped. Discover endpoints via /.well-known/oauth-authorization-server.
Body
Submit a lead form to another company's Discover offer (brand->agency outreach). The sender is the token tenant; agencyCompanyId is the offer-owner agency (intentionally another company). Requires a Pro subscription. Answers are validated against the offer's lead-form config.
The Discover offer/listing id to submit the form to.
The offer-owner agency company id (must not equal the caller).
Submitter name (validated against the offer's contact fields).
Submitter email (validated against the offer's contact fields).
Submitter phone (validated against the offer's contact fields).
Answers to the offer's custom lead-form fields, keyed by field id.
Response
The created lead submission and delivery outcome.
Show child attributes
Show child attributes