Restore a deleted workspace task
Tasks are scoped to the authenticated organization and accessible related records. Managing task content, deletion or reassignment requires task management access; completion may also be allowed for the assigned staff member. Expected version or updated timestamp protects changes from stale data and returns 422 on conflict. CSV and calendar exports use the same visibility and filter rules; calendar exports include only dated tasks.
curl --request POST \
--url https://api.gratona.com/v1/admin/tasks/{task_id}/restore \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expected_updated_at": "2026-10-20T09:00:00Z",
"expected_version": 1
}
'import requests
url = "https://api.gratona.com/v1/admin/tasks/{task_id}/restore"
payload = {
"expected_updated_at": "2026-10-20T09:00:00Z",
"expected_version": 1
}
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({expected_updated_at: '2026-10-20T09:00:00Z', expected_version: 1})
};
fetch('https://api.gratona.com/v1/admin/tasks/{task_id}/restore', 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.gratona.com/v1/admin/tasks/{task_id}/restore",
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([
'expected_updated_at' => '2026-10-20T09:00:00Z',
'expected_version' => 1
]),
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.gratona.com/v1/admin/tasks/{task_id}/restore"
payload := strings.NewReader("{\n \"expected_updated_at\": \"2026-10-20T09:00:00Z\",\n \"expected_version\": 1\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.gratona.com/v1/admin/tasks/{task_id}/restore")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"expected_updated_at\": \"2026-10-20T09:00:00Z\",\n \"expected_version\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/tasks/{task_id}/restore")
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 \"expected_updated_at\": \"2026-10-20T09:00:00Z\",\n \"expected_version\": 1\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"title": "<string>",
"status": "<string>",
"due_date": "2023-12-25",
"due_label": "<string>",
"due_state": "<string>",
"assigned_to_user_id": 123,
"created_by_user_id": 123,
"completed_at": "2023-11-07T05:31:56Z",
"source": "<string>",
"version": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"body_json": {},
"assigned_to": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"created_by": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"completed_by": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"links": [
{
"id": 123,
"record_type": "<string>",
"record_id": 123,
"related_type": "<string>",
"related_id": 123,
"type_label": "<string>",
"program_type": "<string>",
"label": "<string>",
"secondary": "<string>",
"url": "<string>",
"is_primary": true,
"visibility_required": true,
"is_accessible": true
}
],
"mentions": [
{
"id": 123,
"mention_type": "<string>",
"user_id": 123,
"record_type": "<string>",
"record_id": 123,
"related_type": "<string>",
"related_id": 123,
"type_label": "<string>",
"program_type": "<string>",
"label": "<string>",
"is_accessible": true
}
]
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}Authorizations
Passport bearer token authentication for legacy admin sessions.
Path Parameters
Task id.
Body
Request fields accepted by this operation. Omitted optional properties retain the behavior described above.
Response
Restore a deleted workspace task response.
Structured editor document; an empty document may be serialized as an array.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
curl --request POST \
--url https://api.gratona.com/v1/admin/tasks/{task_id}/restore \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expected_updated_at": "2026-10-20T09:00:00Z",
"expected_version": 1
}
'import requests
url = "https://api.gratona.com/v1/admin/tasks/{task_id}/restore"
payload = {
"expected_updated_at": "2026-10-20T09:00:00Z",
"expected_version": 1
}
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({expected_updated_at: '2026-10-20T09:00:00Z', expected_version: 1})
};
fetch('https://api.gratona.com/v1/admin/tasks/{task_id}/restore', 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.gratona.com/v1/admin/tasks/{task_id}/restore",
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([
'expected_updated_at' => '2026-10-20T09:00:00Z',
'expected_version' => 1
]),
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.gratona.com/v1/admin/tasks/{task_id}/restore"
payload := strings.NewReader("{\n \"expected_updated_at\": \"2026-10-20T09:00:00Z\",\n \"expected_version\": 1\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.gratona.com/v1/admin/tasks/{task_id}/restore")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"expected_updated_at\": \"2026-10-20T09:00:00Z\",\n \"expected_version\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/tasks/{task_id}/restore")
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 \"expected_updated_at\": \"2026-10-20T09:00:00Z\",\n \"expected_version\": 1\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"title": "<string>",
"status": "<string>",
"due_date": "2023-12-25",
"due_label": "<string>",
"due_state": "<string>",
"assigned_to_user_id": 123,
"created_by_user_id": 123,
"completed_at": "2023-11-07T05:31:56Z",
"source": "<string>",
"version": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"body_json": {},
"assigned_to": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"created_by": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"completed_by": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"links": [
{
"id": 123,
"record_type": "<string>",
"record_id": 123,
"related_type": "<string>",
"related_id": 123,
"type_label": "<string>",
"program_type": "<string>",
"label": "<string>",
"secondary": "<string>",
"url": "<string>",
"is_primary": true,
"visibility_required": true,
"is_accessible": true
}
],
"mentions": [
{
"id": 123,
"mention_type": "<string>",
"user_id": 123,
"record_type": "<string>",
"record_id": 123,
"related_type": "<string>",
"related_id": 123,
"type_label": "<string>",
"program_type": "<string>",
"label": "<string>",
"is_accessible": true
}
]
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}