Goals

Update Goal

Updates an existing goal.

PUT /api/sites/:site/goals/:goalId

Updates an existing goal. Requires the member role or above on the site (the goals:write permission).

This is a full replacement, not a partial update: send goalType and the whole config every time. Omitting name clears it to null. The body is validated the same way as Create Goal, which documents the GoalConfig fields.

Returns 404 if the goal does not exist and 403 if it belongs to another site.

Path Parameters

Prop

Type

Request Body

Prop

Type

Response

Prop

Type

Request
curl -X PUT "https://app.rybbit.io/api/sites/1/goals/123" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Signup Completed (Updated)",
    "goalType": "path",
    "config": {
      "pathPattern": "/signup/complete/*"
    }
  }'
Request
const response = await fetch(
  'https://app.rybbit.io/api/sites/1/goals/123',
  {
    method: 'PUT',
    headers: {
      'Authorization': 'Bearer your_api_key_here',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name: 'Signup Completed (Updated)',
      goalType: 'path',
      config: {
        pathPattern: '/signup/complete/*'
      }
    })
  }
);

const data = await response.json();
Request
import requests

response = requests.put(
    'https://app.rybbit.io/api/sites/1/goals/123',
    json={
        'name': 'Signup Completed (Updated)',
        'goalType': 'path',
        'config': {
            'pathPattern': '/signup/complete/*'
        }
    },
    headers={
        'Authorization': 'Bearer your_api_key_here'
    }
)

data = response.json()
Request
$body = [
    'name' => 'Signup Completed (Updated)',
    'goalType' => 'path',
    'config' => [
        'pathPattern' => '/signup/complete/*'
    ]
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://app.rybbit.io/api/sites/1/goals/123');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer your_api_key_here',
    'Content-Type: application/json'
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
Request
require 'net/http'
require 'json'

uri = URI('https://app.rybbit.io/api/sites/1/goals/123')
request = Net::HTTP::Put.new(uri)
request['Authorization'] = 'Bearer your_api_key_here'
request['Content-Type'] = 'application/json'
request.body = {
  name: 'Signup Completed (Updated)',
  goalType: 'path',
  config: { pathPattern: '/signup/complete/*' }
}.to_json

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

data = JSON.parse(response.body)
Request
body := map[string]interface{}{
    "name": "Signup Completed (Updated)",
    "goalType": "path",
    "config": map[string]string{
        "pathPattern": "/signup/complete/*",
    },
}
jsonBody, _ := json.Marshal(body)

req, _ := http.NewRequest("PUT", "https://app.rybbit.io/api/sites/1/goals/123", bytes.NewBuffer(jsonBody))
req.Header.Set("Authorization", "Bearer your_api_key_here")
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()

var data map[string]interface{}
json.NewDecoder(resp.Body).Decode(&data)
Request
let body = serde_json::json!({
    "name": "Signup Completed (Updated)",
    "goalType": "path",
    "config": {
        "pathPattern": "/signup/complete/*"
    }
});

let client = reqwest::Client::new();
let res = client
    .put("https://app.rybbit.io/api/sites/1/goals/123")
    .header("Authorization", "Bearer your_api_key_here")
    .json(&body)
    .send()
    .await?;

let data: serde_json::Value = res.json().await?;
Request
String json = """
{
  "name": "Signup Completed (Updated)",
  "goalType": "path",
  "config": {
    "pathPattern": "/signup/complete/*"
  }
}
""";

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://app.rybbit.io/api/sites/1/goals/123"))
    .header("Authorization", "Bearer your_api_key_here")
    .header("Content-Type", "application/json")
    .PUT(HttpRequest.BodyPublishers.ofString(json))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
Request
var body = new
{
    name = "Signup Completed (Updated)",
    goalType = "path",
    config = new { pathPattern = "/signup/complete/*" }
};

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer your_api_key_here");

var content = new StringContent(
    JsonSerializer.Serialize(body),
    Encoding.UTF8,
    "application/json");

var response = await client.PutAsync("https://app.rybbit.io/api/sites/1/goals/123", content);
var data = await response.Content.ReadAsStringAsync();
Response
{
  "success": true,
  "goalId": 1
}