Update an offer
curl --request PATCH \
--url https://api.plane.com/v1/offers/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"recipient": {},
"terms": {},
"expires": "<string>",
"metadata": {}
}
'import requests
url = "https://api.plane.com/v1/offers/{id}"
payload = {
"id": "<string>",
"recipient": {},
"terms": {},
"expires": "<string>",
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({id: '<string>', recipient: {}, terms: {}, expires: '<string>', metadata: {}})
};
fetch('https://api.plane.com/v1/offers/{id}', 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.plane.com/v1/offers/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'id' => '<string>',
'recipient' => [
],
'terms' => [
],
'expires' => '<string>',
'metadata' => [
]
]),
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.plane.com/v1/offers/{id}"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"recipient\": {},\n \"terms\": {},\n \"expires\": \"<string>\",\n \"metadata\": {}\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.plane.com/v1/offers/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"recipient\": {},\n \"terms\": {},\n \"expires\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.plane.com/v1/offers/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"recipient\": {},\n \"terms\": {},\n \"expires\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"recipient": {
"name": "Jane Smith"
},
"terms": {
"role": {
"title": "Senior Software Engineer"
}
},
"expires": "2026-06-27T23:59:59Z",
"metadata": {
"source": "headcount-plan"
}
}
{
"id": "ofr_8kY3pQmNvT2sW9xF",
"object": "offer",
"workspace": "ws_5kR2nLpXvH8dM3yT",
"status": "draft",
"recipient": {
"name": "Jane Smith",
"email": "jane@example.com"
},
"terms": {
"role": {
"title": "Senior Software Engineer",
"responsibilities": "Build and maintain Plane's payroll platform."
},
"employment": {
"starts": "2026-07-15",
"types": ["employee"],
"countries": ["US"]
},
"compensations": [
{
"label": "Base salary",
"amount": "180000.00",
"currency": "USD",
"unit": "year",
"frequency": "twice_monthly",
"stock": "10000 stock options",
"other": null
}
],
"benefits": []
},
"position": null,
"job": null,
"expires": "2026-06-27T23:59:59Z",
"delivery": null,
"decision": null,
"document": null,
"worker": null,
"onboarding": null,
"metadata": {
"source": "headcount-plan"
},
"created": "2026-06-13T16:45:00Z",
"updated": "2026-06-13T17:00:00Z"
}
Offers
Update an offer
Update a draft employment offer.
PATCH
/
v1
/
offers
/
{id}
Update an offer
curl --request PATCH \
--url https://api.plane.com/v1/offers/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"recipient": {},
"terms": {},
"expires": "<string>",
"metadata": {}
}
'import requests
url = "https://api.plane.com/v1/offers/{id}"
payload = {
"id": "<string>",
"recipient": {},
"terms": {},
"expires": "<string>",
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({id: '<string>', recipient: {}, terms: {}, expires: '<string>', metadata: {}})
};
fetch('https://api.plane.com/v1/offers/{id}', 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.plane.com/v1/offers/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'id' => '<string>',
'recipient' => [
],
'terms' => [
],
'expires' => '<string>',
'metadata' => [
]
]),
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.plane.com/v1/offers/{id}"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"recipient\": {},\n \"terms\": {},\n \"expires\": \"<string>\",\n \"metadata\": {}\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.plane.com/v1/offers/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"recipient\": {},\n \"terms\": {},\n \"expires\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.plane.com/v1/offers/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"recipient\": {},\n \"terms\": {},\n \"expires\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"recipient": {
"name": "Jane Smith"
},
"terms": {
"role": {
"title": "Senior Software Engineer"
}
},
"expires": "2026-06-27T23:59:59Z",
"metadata": {
"source": "headcount-plan"
}
}
{
"id": "ofr_8kY3pQmNvT2sW9xF",
"object": "offer",
"workspace": "ws_5kR2nLpXvH8dM3yT",
"status": "draft",
"recipient": {
"name": "Jane Smith",
"email": "jane@example.com"
},
"terms": {
"role": {
"title": "Senior Software Engineer",
"responsibilities": "Build and maintain Plane's payroll platform."
},
"employment": {
"starts": "2026-07-15",
"types": ["employee"],
"countries": ["US"]
},
"compensations": [
{
"label": "Base salary",
"amount": "180000.00",
"currency": "USD",
"unit": "year",
"frequency": "twice_monthly",
"stock": "10000 stock options",
"other": null
}
],
"benefits": []
},
"position": null,
"job": null,
"expires": "2026-06-27T23:59:59Z",
"delivery": null,
"decision": null,
"document": null,
"worker": null,
"onboarding": null,
"metadata": {
"source": "headcount-plan"
},
"created": "2026-06-13T16:45:00Z",
"updated": "2026-06-13T17:00:00Z"
}
Update recipient details, proposed terms, expiration, or metadata on a
draft
offer. Sent, accepted, declined, expired, and voided offers cannot be edited.
Use an Idempotency-Key header when retrying update requests. See
Idempotency.
Parameters
string
required
The offer ID.
object
Recipient name or email.
object
Proposed role, employment constraints, compensations, or benefits.
string
Offer expiration timestamp.
object
Set of key-value pairs to attach to the offer.
Returns
Returns the updated Offer object.{
"recipient": {
"name": "Jane Smith"
},
"terms": {
"role": {
"title": "Senior Software Engineer"
}
},
"expires": "2026-06-27T23:59:59Z",
"metadata": {
"source": "headcount-plan"
}
}
{
"id": "ofr_8kY3pQmNvT2sW9xF",
"object": "offer",
"workspace": "ws_5kR2nLpXvH8dM3yT",
"status": "draft",
"recipient": {
"name": "Jane Smith",
"email": "jane@example.com"
},
"terms": {
"role": {
"title": "Senior Software Engineer",
"responsibilities": "Build and maintain Plane's payroll platform."
},
"employment": {
"starts": "2026-07-15",
"types": ["employee"],
"countries": ["US"]
},
"compensations": [
{
"label": "Base salary",
"amount": "180000.00",
"currency": "USD",
"unit": "year",
"frequency": "twice_monthly",
"stock": "10000 stock options",
"other": null
}
],
"benefits": []
},
"position": null,
"job": null,
"expires": "2026-06-27T23:59:59Z",
"delivery": null,
"decision": null,
"document": null,
"worker": null,
"onboarding": null,
"metadata": {
"source": "headcount-plan"
},
"created": "2026-06-13T16:45:00Z",
"updated": "2026-06-13T17:00:00Z"
}
Was this page helpful?
⌘I