Set the benchmark targets for one scope
Store targets for the account (omit campaign) or for a single campaign (campaign = its Meta id or name, matched case-insensitively against both). Requires an agency key (ak_) — sk_ keys are read-only.
This REPLACES the scope. The body is the complete set of targets for it, so a step you previously stored and now omit is cleared and falls back to the next source in precedence. The response echoes the resulting state so the replacement is never invisible.
Rates are fractions between 0 and 1 — a 2% CTR target is 0.02. A value above 1 is rejected rather than interpreted.
Prefer keying by campaign id: a name-keyed target stops matching when the campaign is renamed. The analysis reports matched_rows: 0 for a target that hit nothing, which is how you spot one that has gone stale.
curl -X PUT "https://mythic-analytics.gulp.workers.dev/client/v1/constraints/benchmarks?location_id=example_string" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"campaign": "120210000000000000",
"benchmarks": {
"ad": 0.02,
"landing": 0.1
},
"note": "Q3 client contract"
}'
import requests
import json
url = "https://mythic-analytics.gulp.workers.dev/client/v1/constraints/benchmarks?location_id=example_string"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"campaign": "120210000000000000",
"benchmarks": {
"ad": 0.02,
"landing": 0.1
},
"note": "Q3 client contract"
}
response = requests.put(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://mythic-analytics.gulp.workers.dev/client/v1/constraints/benchmarks?location_id=example_string", {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"campaign": "120210000000000000",
"benchmarks": {
"ad": 0.02,
"landing": 0.1
},
"note": "Q3 client contract"
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"campaign": "120210000000000000",
"benchmarks": {
"ad": 0.02,
"landing": 0.1
},
"note": "Q3 client contract"
}`)
req, err := http.NewRequest("PUT", "https://mythic-analytics.gulp.workers.dev/client/v1/constraints/benchmarks?location_id=example_string", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://mythic-analytics.gulp.workers.dev/client/v1/constraints/benchmarks?location_id=example_string')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"campaign": "120210000000000000",
"benchmarks": {
"ad": 0.02,
"landing": 0.1
},
"note": "Q3 client contract"
}'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"default": {
"ad": 0.015
},
"default_notes": {},
"campaigns": [
{
"campaign": "example_string",
"benchmarks": {},
"notes": {}
}
],
"updated_at": "2024-12-25T10:00:00Z",
"precedence": [
"example_string"
],
"valid_steps": [
"ad"
],
"saved": {
"scope": "example_string",
"campaign": "example_string",
"benchmarks": {}
},
"note": "example_string"
}
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
{
"error": "Forbidden",
"message": "You don't have permission to access this resource",
"code": 403
}
/client/v1/constraints/benchmarks
Target server for requests. Edit to use your own host.
Agency key (ak_) or location secret key (sk_). Scoped keys (mcp_) are accepted too and need constraints:read or constraints:write. See Using an mcp_ key over HTTP.
ak_) or location secret key (sk_). Scoped keys (mcp_) are accepted too and need constraints:read or constraints:write. See Using an mcp_ key over HTTP.The media type of the request body
Campaign id or name. Omit (or send null) for the account-wide default scope.
Step → rate. Valid steps are ad, tracking, landing, sales, site. Unlike the query params, a stored scope may hold both site and landing/sales targets — which apply depends on whether the analysis request passes lead_event, and the analysis reports any that sat out.
Where the target came from (client contract, category median). Surfaced next to the verdict it produced, so a benchmark is always traceable.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Agency key (ak_) or location secret key (sk_). Scoped keys (mcp_) are accepted too and need constraints:read or constraints:write. See Using an mcp_ key over HTTP.
Query Parameters
Body
Campaign id or name. Omit (or send null) for the account-wide default scope.
Step → rate. Valid steps are ad, tracking, landing, sales, site. Unlike the query params, a stored scope may hold both site and landing/sales targets — which apply depends on whether the analysis request passes lead_event, and the analysis reports any that sat out.
{"ad":0.02,"landing":0.1}Where the target came from (client contract, category median). Surfaced next to the verdict it produced, so a benchmark is always traceable.