Geliştiriciler
Planitude ile geliştirin
Bir REST API, imzalı webhook'lar ve bir MCP sunucusu: sistemlerinizi plana göre eşitli tutun, her değişikliğe tepki verin ve bir yapay zekâ asistanının projelerinizde çalışmasına izin verin.
Kod, alan adları ve teknik başvuru kaynağı, çoğu API belgesinde olduğu gibi İngilizcedir.
- Görevleri sistemlerinizle eşitleyinBir CRM'den, ERP'den veya betikten proje ve görev oluşturun,
externalIdile kendi kimliğinizden yeniden bulun ve tarihleri zamanlama motoruna hesaplatın. - Her değişikliğe tepki verinDeğişiklik uygulamadan, API'den, bir içe aktarmadan veya bir yapay zekâ asistanından gelsin; bir görev oluşturulduğunda, tamamlandığında veya taşındığında imzalı bir HTTPS isteği alın.
- Bir yapay zekâ asistanı bağlayınChatGPT, Claude, Gemini, Cursor ve VS Code, planlarınızı okur ve değişiklikleri MCP sunucusu üzerinden önerir; yalnızca sizin izinlerinizle, fazlasıyla değil.
Temel URL: https://planitude.app
İstekler ve yanıtlar HTTPS üzerinden JSON'dur. Süreler ve gecikmeler çalışma dakikası cinsindendir (8 saatlik gün 480'dir), zaman noktaları UTC'de ISO 8601'dir, saatsiz tarihler YYYY-MM-DD biçimindedir.
curl https://planitude.app/api/auth/me \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/auth/me", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/auth/me",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"user": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"email": "[email protected]",
"name": "Anna Rossi",
"avatarUrl": null,
"locale": "en",
"emailVerified": true
}
}Hızlı başlangıç
Sıfırdan ilk webhook'unuza üç adımda. Tek ihtiyacınız bir terminal.
API anahtarı oluşturun
Profil → API anahtarları bölümünü açın, Okuma ve yazma seçeneğini seçin ve anahtarı kopyalayın:
gnt_ile başlar ve yalnızca bir kez gösterilir. Bir ortam değişkeninde saklayın.İlk çağrınızı yapın
Görebildiğiniz projeleri listeleyin. Anahtar sizin adınıza hareket eder: aynı projeler, aynı roller.
Bir webhook alın
Herkese açık bir HTTPS uç noktasını ihtiyacınız olan olaylara abone edin, ardından hemen bir test olayı gönderin ve imzasını doğrulayın.
export PLANITUDE_API_KEY="gnt_…"curl https://planitude.app/api/projects \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"projects": [
{
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"keyLocked": false,
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"calendarId": null,
"currency": "EUR",
"scheduleFrom": "forward",
"deadline": null,
"color": null,
"settings": {},
"archivedAt": null,
"createdBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"workspaceName": "Acme Construction",
"role": "owner",
"taskCount": 12,
"finishAt": "2026-10-07T15:00:00.000Z"
}
]
}curl -X POST https://planitude.app/api/webhooks \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8"
}'const res = await fetch("https://planitude.app/api/webhooks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/hooks/planitude",
events: ["task.created", "task.completed"],
projectId: "40be00e0-7e34-4f7a-864b-5cc986f575b8",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/webhooks",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"url": "https://example.com/hooks/planitude",
"events": ["task.created", "task.completed"],
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
},
)
res.raise_for_status()
print(res.json()){
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "webhook.ping",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"message": "Planitude webhook test",
"webhook": {
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"name": "Warehouse sync",
"events": [
"task.created",
"task.completed"
]
}
}
}Kimlik doğrulama
Her isteği, Authorization üst bilgisinde taşıyıcı belirteç olarak kişisel bir API anahtarıyla doğrulayın. Anahtarlar kişiseldir: sizin adınıza, her projedeki rolünüzle hareket eder, asla daha fazlasıyla değil. Bir anahtarı tek bir çalışma alanıyla sınırlayabilir, ona son kullanma tarihi verebilir ve istediğiniz zaman iptal edebilirsiniz; her çağrı anahtarın yanında günlüğe kaydedilir.
Kapsamlar
| Kapsam | İzin verir |
|---|---|
| readplanitude:read | Projeleri, görevleri, bağımlılıkları, üyeleri, yorumları, temel planları ve webhook'ları okuma. |
| writeplanitude:write | Okumadaki her şey; ayrıca projeleri, görevleri, bağımlılıkları, yorumları, temel planları ve webhook'ları oluşturma ve değiştirme. |
Anahtarlar ve OAuth uygulamaları projeleri veya görevleri silemez: silme işlemi, bir kişinin onayladığı web uygulamasında kalır. Yanlış kimliği hedefleyen bir betik planı silemez.
Üçüncü taraf uygulamalar için OAuth 2.1
Başkaları adına hareket eden uygulamalar OAuth 2.1 kullanır: PKCE (S256) ile yetkilendirme kodu, her kullanımda yenilenen yenileme belirteçleri, dinamik istemci kaydı (RFC 7591). https://planitude.app/api kaynağını ve planitude:read veya planitude:write kapsamını isteyin.
Uç noktalar standart keşif belgelerinde yayımlanır; bu sayede OAuth kitaplıkları kendini yapılandırır.
https://planitude.app/.well-known/oauth-authorization-serverhttps://planitude.app/.well-known/oauth-protected-resource
İyi uygulamalar
- Anahtarları ortam değişkenlerinde veya bir gizli bilgi yöneticisinde saklayın; asla kodda veya bir depoda değil. Anahtarlar
gnt_ile başladığından, gizli bilgi tarayıcıları bunları tespit edebilir. - Yalnızca okuyorsanız salt okunur bir anahtar kullanın ve her entegrasyon için ayrı bir anahtar kullanın: diğerlerini durdurmadan birini iptal edebilirsiniz.
- Betiklerin kullandığı anahtarlara son kullanma tarihi verin ve düzenli olarak yenileyin.
- API'yi tarayıcıdan değil, sunucunuzdan çağırın: ön yüz kodundaki bir anahtar herkese açık bir anahtardır.
curl https://planitude.app/api/projects \
-H "Authorization: Bearer $PLANITUDE_API_KEY"{
"issuer": "https://planitude.app",
"authorization_endpoint": "https://planitude.app/oauth/authorize",
"token_endpoint": "https://planitude.app/api/oauth/token",
"registration_endpoint": "https://planitude.app/api/oauth/register",
"revocation_endpoint": "https://planitude.app/api/oauth/revoke",
"scopes_supported": [
"planitude:read",
"planitude:write"
],
"grant_types_supported": [
"authorization_code",
"refresh_token"
],
"code_challenge_methods_supported": [
"S256"
]
}Hatalar
Planitude standart HTTP durum kodlarını kullanır. Hatalar her zaman aynı JSON yapısındadır: dallanma için kararlı bir error kodu ve gerektiğinde gerekçeyi veya düzeltilecek alanları içeren details.
| Durum | Anlamı |
|---|---|
| 400invalid_request | İstek geçerli değil: details.fields, her alanı ve sorunu listeler. |
| 401unauthorized | Anahtar eksik, geçersiz, iptal edilmiş veya süresi dolmuş. |
| 403forbidden | Anahtar veya rolünüz buna izin vermiyor (details.reason); örneğin salt okunur anahtarla yazma veya silme. |
| 404not_found | Bulunamadı veya size görünür değil. |
| 409dependency_cycle | Planla çakışma; örneğin bir döngü oluşturacak bir bağımlılık (dependency_cycle). |
| 429rate_limited | Çok fazla istek: Retry-After içindeki saniye kadar bekleyin. |
| 500server_error | Bizim tarafımızda bir sorun oluştu: üstel geri çekilmeyle yeniden deneyin. |
Error
| Alan | Tür | Açıklama |
|---|---|---|
| error zorunlu | string | Stable error code: invalid_request, unauthorized, forbidden, not_found, conflict, dependency_cycle, limit_exceeded, rate_limited, server_error, ... |
| details | object |
{
"error": "invalid_request",
"details": {
"fields": [
{
"path": "name",
"message": "Invalid input: expected string, received undefined"
},
{
"path": "durationMin",
"message": "Too small: expected number to be >=0"
}
]
}
}{
"error": "forbidden",
"details": {
"reason": "destructive"
}
}{
"error": "dependency_cycle",
"details": {
"cycles": [
{
"path": "Foundations -> Walls -> Foundations",
"taskIds": [
"4dbd104a-00cd-4035-8955-255f52ea586a",
"a22fd799-c4dc-4869-a466-0dd6e96f71ce"
],
"taskNames": [
"Foundations",
"Walls"
]
}
]
}
}İstek sınırları
Sınırlar anahtar başına, bir dakikalık kayan pencerede uygulanır: 240 okuma isteği ve 60 yazma isteği. Sınır aşıldığında, saniye cinsinden bir Retry-After üst bilgisiyle 429 rate_limited alırsınız.
Yeniden denemeden önce Retry-After süresini bekleyin, toplu işleri zamana yayın ve çok sayıda değişikliği tek bir değişiklik kümesinde toplayın: tek istekte ve tek yeniden hesaplamada en fazla 1.000 değişiklik.
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
{
"error": "rate_limited",
"details": {
"retryAfterSec": 12
}
}Sayfalama ve arama
Görev listeleri imleçle sayfalanır. limit (1–500, varsayılan 100) değerini ve sonraki sayfa için önceki yanıttaki nextCursor değerini cursor olarak iletin. nextCursor değeri null olduğunda başka sayfa yoktur.
externalId (kendi kimliğinizde tam eşleşme), q (ad şunu içerir), updatedSince ve completed ile filtreleyin; sort=-number (en yeni önce) veya -updatedAt ile sıralayın. Projeler, üyeler ve bağımlılıklar gibi daha kısa listeler tek yanıtta bütün olarak gelir.
curl "https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks?limit=500" \
-H "Authorization: Bearer $PLANITUDE_API_KEY"
# next page: pass the nextCursor of the previous response
curl "https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks?limit=500&cursor=$NEXT_CURSOR" \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const tasks = [];
let cursor = null;
do {
const url = new URL("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks");
url.searchParams.set("limit", "500");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}` },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const page = await res.json();
tasks.push(...page.tasks);
cursor = page.nextCursor;
} while (cursor);
console.log(tasks.length);import os
import requests
tasks, cursor = [], None
while True:
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
params={"limit": 500, **({"cursor": cursor} if cursor else {})},
)
res.raise_for_status()
page = res.json()
tasks += page["tasks"]
cursor = page["nextCursor"]
if not cursor:
break
print(len(tasks))Sürümleme
API ve webhook yükleri tarihe göre sürümlenir. Geçerli sürüm 2026-10-01'dır: her olayın apiVersion alanı ve OpenAPI belgesinin info.version değeridir.
Bir sürüm içinde yalnızca ekleme yaparız: yeni uç noktalar, yeni isteğe bağlı alanlar, yeni olay türleri. Alanlar yeni sürüm olmadan asla kaldırılmaz veya türü değiştirilmez; bu yüzden bilmediğiniz alanları yok sayın.
curl https://planitude.app/api/webhooks/eventsconst res = await fetch("https://planitude.app/api/webhooks/events");
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import requests
res = requests.get("https://planitude.app/api/webhooks/events")
res.raise_for_status()
print(res.json()){
"apiVersion": "2026-10-01",
"events": [
"project.created",
"project.updated",
"project.deleted",
"task.created",
"task.updated",
"task.deleted",
"task.completed",
"task.dates_changed",
"dependency.created",
"dependency.deleted",
"baseline.saved",
"member.invited",
"member.joined",
"comment.created"
]
}API başvurusu
Account
Who is calling, and their workspaces.
User
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| string (email) | ||
| name | stringboş olabilir | |
| avatarUrl | stringboş olabilir | |
| locale | string | |
| emailVerified | boolean |
{
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"email": "[email protected]",
"name": "Anna Rossi",
"avatarUrl": null,
"locale": "en",
"emailVerified": true
}Workspace
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| name | string | |
| role | string | Şunlardan biri: |
{
"id": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"name": "Acme Construction",
"role": "owner"
}Current user (connection test)
GET/api/auth/me
Okuma erişimli anahtar
Döndürür
200 OK The user
| Alan | Tür | Açıklama |
|---|---|---|
| user | User |
curl https://planitude.app/api/auth/me \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/auth/me", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/auth/me",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"user": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"email": "[email protected]",
"name": "Anna Rossi",
"avatarUrl": null,
"locale": "en",
"emailVerified": true
}
}Workspaces of the user, with role
GET/api/workspaces
Okuma erişimli anahtar
Döndürür
200 OK Workspaces
| Alan | Tür | Açıklama |
|---|---|---|
| workspaces | array of Workspace |
curl https://planitude.app/api/workspaces \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/workspaces", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/workspaces",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"workspaces": [
{
"id": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"name": "Acme Construction",
"role": "owner"
}
]
}API başvurusu
Projects
Projects, templates and baselines.
Project
A project as returned by the write endpoints and project listings.
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| workspaceId | string (uuid) | |
| key | string | Project key, e.g. CRON (task keys are CRON-12). |
| keyLocked | boolean | |
| name | string | |
| description | stringboş olabilir | |
| startDate | string (date) | |
| calendarId | string (uuid)boş olabilir | |
| currency | string | |
| scheduleFrom | string | Şunlardan biri: |
| deadline | string (date)boş olabilir | |
| color | stringboş olabilir | |
| settings | object | |
| archivedAt | string (date-time)boş olabilir | |
| createdBy | string (uuid)boş olabilir | |
| createdAt | string (date-time) | |
| updatedAt | string (date-time) |
{
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"keyLocked": false,
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"calendarId": null,
"currency": "EUR",
"scheduleFrom": "forward",
"deadline": null,
"color": null,
"settings": {},
"archivedAt": null,
"createdBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z"
}Template
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string | builtin:<slug> or the id of a template saved by you. |
| kind | string | Şunlardan biri: |
| name | string | |
| description | stringboş olabilir | |
| taskCount | integer | |
| durationDays | integer | Working days from start to finish. |
{
"id": "builtin:website-launch",
"kind": "builtin",
"name": "Website launch",
"description": "From discovery to go-live: design, content, development, testing and launch.",
"taskCount": 12,
"durationDays": 43
}Baseline
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| name | string | |
| index | integerboş olabilir | Numbered MS Project baseline (1-10); null for the main baseline and the ones you name. |
| capturedAt | string (date-time) | |
| capturedBy | string (uuid)boş olabilir | |
| taskCount | integer |
{
"id": "b5d68d05-0640-48f9-8eeb-ed7804f4a116",
"name": "Plan v1",
"index": null,
"capturedAt": "2026-10-01T08:30:12.418Z",
"capturedBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"taskCount": 12
}List projects
GET/api/projects
Okuma erişimli anahtar
All projects visible to the user (not paginated). ?archived=1 includes archived ones.
Sorgu parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| archived | string | Şunlardan biri: |
Döndürür
200 OK Projects
| Alan | Tür | Açıklama |
|---|---|---|
| projects | array of Project |
curl https://planitude.app/api/projects \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"projects": [
{
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"keyLocked": false,
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"calendarId": null,
"currency": "EUR",
"scheduleFrom": "forward",
"deadline": null,
"color": null,
"settings": {},
"archivedAt": null,
"createdBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"workspaceName": "Acme Construction",
"role": "owner",
"taskCount": 12,
"finishAt": "2026-10-07T15:00:00.000Z"
}
]
}Create a project
POST/api/projects
Yazma erişimli anahtar
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| name zorunlu | string | |
| workspaceId | string (uuid) | Defaults to your personal workspace. |
| key | string | 2-5 letters/digits, starts with a letter. Derived from the name if omitted. |
| description | stringboş olabilir | |
| startDate | string (date) | |
| deadline | string (date)boş olabilir | |
| currency | string | |
| scheduleFrom | string | Şunlardan biri: |
| color | stringboş olabilir |
Döndürür
201 Created Created
| Alan | Tür | Açıklama |
|---|---|---|
| project | Project |
curl -X POST https://planitude.app/api/projects \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Warehouse expansion","startDate":"2026-10-05","currency":"EUR"}'const res = await fetch("https://planitude.app/api/projects", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Warehouse expansion",
startDate: "2026-10-05",
currency: "EUR",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/projects",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"name": "Warehouse expansion",
"startDate": "2026-10-05",
"currency": "EUR",
},
)
res.raise_for_status()
print(res.json()){
"project": {
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"keyLocked": false,
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"calendarId": null,
"currency": "EUR",
"scheduleFrom": "forward",
"deadline": null,
"color": null,
"settings": {},
"archivedAt": null,
"createdBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z"
}
}Create a project from a template
POST/api/projects/from-template
Yazma erişimli anahtar
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| templateId zorunlu | string | Id from GET /api/templates. |
| startDate zorunlu | string (date) | |
| name | string | |
| key | string | |
| locale | string | Language of the template texts (en, it, es, fr, de, pt, nl, pl, ja, zh, sv, da, no, fi, cs, ro, uk, tr, ar, he, hi, id, vi, ko). |
| tz | string | IANA time zone of the project calendar. |
| workspaceId | string (uuid) |
Döndürür
201 Created Created
| Alan | Tür | Açıklama |
|---|---|---|
| project | Project | |
| taskCount | integer | |
| conflicts | array of Conflict |
curl -X POST https://planitude.app/api/projects/from-template \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "builtin:website-launch",
"startDate": "2026-10-05",
"name": "Website relaunch",
"locale": "en"
}'const res = await fetch("https://planitude.app/api/projects/from-template", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
templateId: "builtin:website-launch",
startDate: "2026-10-05",
name: "Website relaunch",
locale: "en",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/projects/from-template",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"templateId": "builtin:website-launch",
"startDate": "2026-10-05",
"name": "Website relaunch",
"locale": "en",
},
)
res.raise_for_status()
print(res.json()){
"project": {
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"keyLocked": false,
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"calendarId": null,
"currency": "EUR",
"scheduleFrom": "forward",
"deadline": null,
"color": null,
"settings": {},
"archivedAt": null,
"createdBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z"
},
"taskCount": 12,
"conflicts": []
}List project templates
GET/api/templates
Okuma erişimli anahtar
Sorgu parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| locale | string |
Döndürür
200 OK Templates
| Alan | Tür | Açıklama |
|---|---|---|
| templates | array of Template |
curl https://planitude.app/api/templates \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/templates", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/templates",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"templates": [
{
"id": "builtin:website-launch",
"kind": "builtin",
"name": "Website launch",
"description": "From discovery to go-live: design, content, development, testing and launch.",
"taskCount": 12,
"durationDays": 43
}
]
}Full project (tasks tree, dependencies, resources, members, baselines)
GET/api/projects/{projectId}
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
Döndürür
200 OK Project
| Alan | Tür | Açıklama |
|---|---|---|
| project | Project | |
| tasks | array of Task | |
| dependencies | array of Dependency |
curl https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8 \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"project": {
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"keyLocked": false,
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"calendarId": null,
"currency": "EUR",
"scheduleFrom": "forward",
"deadline": null,
"color": null,
"settings": {},
"archivedAt": null,
"createdBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z"
},
"tasks": [
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"sortKey": "i",
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null
}
],
"dependencies": [
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
]
}Update a project
PATCH/api/projects/{projectId}
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| name | string | |
| description | stringboş olabilir | |
| startDate | string (date) | |
| deadline | string (date)boş olabilir | |
| currency | string | |
| scheduleFrom | string | Şunlardan biri: |
| color | stringboş olabilir | |
| archived | boolean |
Döndürür
200 OK Updated
| Alan | Tür | Açıklama |
|---|---|---|
| project | Project | |
| conflicts | array of Conflict | |
| rescheduled | boolean | The schedule was recalculated (start date, calendar or direction changed). |
curl -X PATCH https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8 \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"deadline":"2026-12-18"}'const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
deadline: "2026-12-18",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.patch(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"deadline": "2026-12-18",
},
)
res.raise_for_status()
print(res.json()){
"project": {
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"keyLocked": false,
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"calendarId": null,
"currency": "EUR",
"scheduleFrom": "forward",
"deadline": null,
"color": null,
"settings": {},
"archivedAt": null,
"createdBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z"
},
"conflicts": [],
"rescheduled": false
}List baselines
GET/api/projects/{projectId}/baseline
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
Döndürür
200 OK Baselines
| Alan | Tür | Açıklama |
|---|---|---|
| baselines | array of Baseline |
curl https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/baseline \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/baseline", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/baseline",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"baselines": [
{
"id": "b5d68d05-0640-48f9-8eeb-ed7804f4a116",
"name": "Plan v1",
"index": null,
"capturedAt": "2026-10-01T08:30:12.418Z",
"capturedBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"taskCount": 12
}
]
}Save a baseline
POST/api/projects/{projectId}/baseline
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| name | string |
Döndürür
201 Created Saved
| Alan | Tür | Açıklama |
|---|---|---|
| baseline | Baseline |
curl -X POST https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/baseline \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Plan v1"}'const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/baseline", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Plan v1",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/baseline",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"name": "Plan v1",
},
)
res.raise_for_status()
print(res.json()){
"baseline": {
"id": "b5d68d05-0640-48f9-8eeb-ed7804f4a116",
"name": "Plan v1",
"index": null,
"capturedAt": "2026-10-01T08:30:12.418Z",
"capturedBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"taskCount": 12
}
}API başvurusu
Tasks
Tasks, search by external id, comments.
Task
Task representation of GET /tasks and webhook payloads: the stored task (without sortKey) plus project, assignees and link.
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| number | integer | Sequential number in the project, never reused. |
| key | string | Human key, e.g. CRON-12. |
| parentId | string (uuid)boş olabilir | |
| name | string | |
| type | string | Şunlardan biri: |
| durationMin | integer | Duration in working minutes (8h day = 480). |
| workMin | integer | |
| progressPct | number | |
| constraintKind | string | Şunlardan biri: |
| constraintDate | string (date-time)boş olabilir | |
| deadline | string (date-time)boş olabilir | |
| calendarId | string (uuid)boş olabilir | |
| costFixed | number | |
| notes | stringboş olabilir | |
| color | stringboş olabilir | |
| wbs | stringboş olabilir | |
| externalId | stringboş olabilir | Your identifier for this task in another system. Searchable with GET /tasks?externalId=. |
| startAt | string (date-time)boş olabilir | Computed start. |
| finishAt | string (date-time)boş olabilir | Computed finish. |
| isCritical | boolean | On the critical path. |
| totalFloatMin | integerboş olabilir | Total float (slack) in working minutes. |
| earlyStartAt | string (date-time)boş olabilir | |
| lateFinishAt | string (date-time)boş olabilir | |
| actualStartAt | string (date-time)boş olabilir | |
| actualFinishAt | string (date-time)boş olabilir | |
| actualDurationMin | integerboş olabilir | |
| remainingDurationMin | integerboş olabilir | |
| manuallyScheduled | boolean | |
| levelingDelayMin | integer | |
| taskType | string | Şunlardan biri: |
| effortDriven | boolean | |
| durationOptimisticMin | integerboş olabilir | |
| durationPessimisticMin | integerboş olabilir | |
| projectId | string (uuid) | |
| completed | boolean | progressPct = 100. |
| assignees | array of Assignee | |
| url | string (uri) | Page of the task in the web app. |
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
}WriteResult
Öznitelikler
| Alan | Tür | Açıklama | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tasks | array of Task | Created/updated tasks plus the ones the recalculation moved. | |||||||||||||||
| deletedTaskIds | array of string | ||||||||||||||||
| dependencies | array of Dependency | ||||||||||||||||
| deletedDependencyIds | array of string | ||||||||||||||||
| conflicts | array of Conflict | ||||||||||||||||
| projectStartAt | string (date-time) | ||||||||||||||||
| projectFinishAt | string (date-time) | ||||||||||||||||
| stats | object | stats alanlarını göster
|
{
"tasks": [
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"sortKey": "i",
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null
}
],
"deletedTaskIds": [],
"dependencies": [
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
],
"deletedDependencyIds": [],
"conflicts": [],
"projectStartAt": "2026-10-05T06:00:00.000Z",
"projectFinishAt": "2026-10-07T15:00:00.000Z",
"stats": {
"taskCount": 12,
"recomputedCount": 3,
"savedCount": 2,
"durationMs": 39
}
}Comment
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| taskId | string (uuid) | |
| userId | string (uuid) | |
| authorName | string | |
| authorAvatarUrl | stringboş olabilir | |
| body | string | |
| mentions | array of string | |
| createdAt | string (date-time) | |
| editedAt | string (date-time)boş olabilir |
{
"id": "0fc2dec5-a409-47c9-9c6e-0663e8f8bcf3",
"taskId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"authorName": "Anna Rossi",
"authorAvatarUrl": null,
"body": "Concrete delivered, we can start the walls.",
"mentions": [],
"createdAt": "2026-10-01T08:30:12.418Z",
"editedAt": null
}List or search tasks (paginated)
GET/api/projects/{projectId}/tasks
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
Sorgu parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| limit | integer | 1-500. Varsayılan: |
| cursor | string | nextCursor of the previous page. |
| sort | string | -number = newest first (polling triggers). -updatedAt returns the first page only.Şunlardan biri: Varsayılan: |
| externalId | string | Exact match on externalId. |
| q | string | Name contains (case-insensitive). |
| updatedSince | string (date-time) | |
| completed | string | Şunlardan biri: |
Döndürür
200 OK A page of tasks
| Alan | Tür | Açıklama |
|---|---|---|
| tasks | array of Task | |
| nextCursor | stringboş olabilir |
curl "https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks?externalId=crm-4711" \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks?externalId=crm-4711", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
params={
"externalId": "crm-4711",
},
)
res.raise_for_status()
print(res.json()){
"tasks": [
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
}
],
"nextCursor": null
}Create a task, or apply a change set
POST/api/projects/{projectId}/tasks
Yazma erişimli anahtar
Send a TaskCreate to create one task (201), or a ChangeSet to apply several changes in one transaction (200). Dates are recalculated by the scheduling engine.
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
İstek gövdesi
TaskCreate
| Alan | Tür | Açıklama |
|---|---|---|
| name zorunlu | string | |
| parentId | string (uuid)boş olabilir | Parent (summary) task; null = top level. |
| afterTaskId | string (uuid)boş olabilir | Insert after this sibling. |
| beforeTaskId | string (uuid)boş olabilir | Insert before this sibling. |
| type | string | Şunlardan biri: |
| durationMin | integer | Duration in working minutes (8h day = 480). |
| workMin | integer | |
| progressPct | number | |
| constraintKind | string | Şunlardan biri: |
| constraintDate | string (date-time)boş olabilir | |
| deadline | string (date-time)boş olabilir | |
| calendarId | string (uuid)boş olabilir | |
| costFixed | number | |
| notes | stringboş olabilir | |
| color | stringboş olabilir | |
| wbs | stringboş olabilir | |
| externalId | stringboş olabilir | Your identifier for this task in another system. Searchable with GET /tasks?externalId=. |
veya ChangeSet
| Alan | Tür | Açıklama |
|---|---|---|
| createTasks | array of TaskCreate | |
| updateTasks | array of any | |
| createDependencies | array of DependencyCreate | |
| deleteDependencyIds | array of string | |
| fullReschedule | boolean |
Döndürür
201 Created Task created
| Alan | Tür | Açıklama | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tasks | array of Task | Created/updated tasks plus the ones the recalculation moved. | |||||||||||||||
| deletedTaskIds | array of string | ||||||||||||||||
| dependencies | array of Dependency | ||||||||||||||||
| deletedDependencyIds | array of string | ||||||||||||||||
| conflicts | array of Conflict | ||||||||||||||||
| projectStartAt | string (date-time) | ||||||||||||||||
| projectFinishAt | string (date-time) | ||||||||||||||||
| stats | object | stats alanlarını göster
|
curl -X POST https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Foundations","durationMin":1440,"externalId":"crm-4711"}'const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Foundations",
durationMin: 1440,
externalId: "crm-4711",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"name": "Foundations",
"durationMin": 1440,
"externalId": "crm-4711",
},
)
res.raise_for_status()
print(res.json()){
"tasks": [
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"sortKey": "i",
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null
}
],
"deletedTaskIds": [],
"dependencies": [
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
],
"deletedDependencyIds": [],
"conflicts": [],
"projectStartAt": "2026-10-05T06:00:00.000Z",
"projectFinishAt": "2026-10-07T15:00:00.000Z",
"stats": {
"taskCount": 12,
"recomputedCount": 3,
"savedCount": 2,
"durationMs": 39
}
}Get a task
GET/api/projects/{projectId}/tasks/{taskId}
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
| taskId zorunlu | string (uuid) | Task id. |
Döndürür
200 OK The task
| Alan | Tür | Açıklama |
|---|---|---|
| task | Task |
curl https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"task": {
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
}
}Update a task
PATCH/api/projects/{projectId}/tasks/{taskId}
Yazma erişimli anahtar
Only the fields you send change; null clears a field.
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
| taskId zorunlu | string (uuid) | Task id. |
İstek gövdesi
| Alan | Tür | Açıklama | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | |||||||||||||
| type | string | Şunlardan biri: | ||||||||||||
| durationMin | integer | Duration in working minutes (8h day = 480). | ||||||||||||
| workMin | integer | |||||||||||||
| progressPct | number | |||||||||||||
| constraintKind | string | Şunlardan biri: | ||||||||||||
| constraintDate | string (date-time)boş olabilir | |||||||||||||
| deadline | string (date-time)boş olabilir | |||||||||||||
| calendarId | string (uuid)boş olabilir | |||||||||||||
| costFixed | number | |||||||||||||
| notes | stringboş olabilir | |||||||||||||
| color | stringboş olabilir | |||||||||||||
| wbs | stringboş olabilir | |||||||||||||
| externalId | stringboş olabilir | Your identifier for this task in another system. Searchable with GET /tasks?externalId=. | ||||||||||||
| placement | object | placement alanlarını göster
|
Döndürür
200 OK Updated
| Alan | Tür | Açıklama | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tasks | array of Task | Created/updated tasks plus the ones the recalculation moved. | |||||||||||||||
| deletedTaskIds | array of string | ||||||||||||||||
| dependencies | array of Dependency | ||||||||||||||||
| deletedDependencyIds | array of string | ||||||||||||||||
| conflicts | array of Conflict | ||||||||||||||||
| projectStartAt | string (date-time) | ||||||||||||||||
| projectFinishAt | string (date-time) | ||||||||||||||||
| stats | object | stats alanlarını göster
|
curl -X PATCH https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"progressPct":100}'const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
progressPct: 100,
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.patch(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"progressPct": 100,
},
)
res.raise_for_status()
print(res.json()){
"tasks": [
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"sortKey": "i",
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null
}
],
"deletedTaskIds": [],
"dependencies": [
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
],
"deletedDependencyIds": [],
"conflicts": [],
"projectStartAt": "2026-10-05T06:00:00.000Z",
"projectFinishAt": "2026-10-07T15:00:00.000Z",
"stats": {
"taskCount": 12,
"recomputedCount": 3,
"savedCount": 2,
"durationMs": 39
}
}Comments of a task
GET/api/projects/{projectId}/tasks/{taskId}/comments
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
| taskId zorunlu | string (uuid) | Task id. |
Döndürür
200 OK Comments
| Alan | Tür | Açıklama |
|---|---|---|
| comments | array of Comment |
curl https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/comments \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/comments", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/comments",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"comments": [
{
"id": "0fc2dec5-a409-47c9-9c6e-0663e8f8bcf3",
"taskId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"authorName": "Anna Rossi",
"authorAvatarUrl": null,
"body": "Concrete delivered, we can start the walls.",
"mentions": [],
"createdAt": "2026-10-01T08:30:12.418Z",
"editedAt": null
}
]
}Comment on a task
POST/api/projects/{projectId}/tasks/{taskId}/comments
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
| taskId zorunlu | string (uuid) | Task id. |
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| body zorunlu | string | Plain text. |
| mentions | array of string | User ids to notify. |
Döndürür
201 Created Created
| Alan | Tür | Açıklama |
|---|---|---|
| comment | Comment |
curl -X POST https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/comments \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"Concrete delivered, we can start the walls."}'const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/comments", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
body: "Concrete delivered, we can start the walls.",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/comments",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"body": "Concrete delivered, we can start the walls.",
},
)
res.raise_for_status()
print(res.json()){
"comment": {
"id": "0fc2dec5-a409-47c9-9c6e-0663e8f8bcf3",
"taskId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"authorName": "Anna Rossi",
"authorAvatarUrl": null,
"body": "Concrete delivered, we can start the walls.",
"mentions": [],
"createdAt": "2026-10-01T08:30:12.418Z",
"editedAt": null
}
}API başvurusu
Dependencies
Links between tasks (FS, SS, FF, SF, with lag).
Dependency
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| predecessorId | string (uuid) | |
| successorId | string (uuid) | |
| type | string | Şunlardan biri: |
| lagMin | integer | Working minutes; negative = lead. |
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}List dependencies
GET/api/projects/{projectId}/dependencies
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
Döndürür
200 OK Dependencies
| Alan | Tür | Açıklama |
|---|---|---|
| dependencies | array of Dependency |
curl https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"dependencies": [
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
]
}Create (or update) a dependency
POST/api/projects/{projectId}/dependencies
Yazma erişimli anahtar
A dependency that would close a cycle is refused with 409 dependency_cycle.
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
İstek gövdesi
DependencyCreate
| Alan | Tür | Açıklama |
|---|---|---|
| predecessorId zorunlu | string (uuid) | |
| successorId zorunlu | string (uuid) | |
| type | string | Şunlardan biri: Varsayılan: |
| lagMin | integer | Varsayılan: |
veya dependencies
| Alan | Tür | Açıklama |
|---|---|---|
| dependencies zorunlu | array of DependencyCreate |
Döndürür
201 Created Created
| Alan | Tür | Açıklama | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tasks | array of Task | Created/updated tasks plus the ones the recalculation moved. | |||||||||||||||
| deletedTaskIds | array of string | ||||||||||||||||
| dependencies | array of Dependency | ||||||||||||||||
| deletedDependencyIds | array of string | ||||||||||||||||
| conflicts | array of Conflict | ||||||||||||||||
| projectStartAt | string (date-time) | ||||||||||||||||
| projectFinishAt | string (date-time) | ||||||||||||||||
| stats | object | stats alanlarını göster
|
curl -X POST https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}'const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
predecessorId: "4dbd104a-00cd-4035-8955-255f52ea586a",
successorId: "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
type: "FS",
lagMin: 0,
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0,
},
)
res.raise_for_status()
print(res.json()){
"tasks": [
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"sortKey": "i",
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null
}
],
"deletedTaskIds": [],
"dependencies": [
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
],
"deletedDependencyIds": [],
"conflicts": [],
"projectStartAt": "2026-10-05T06:00:00.000Z",
"projectFinishAt": "2026-10-07T15:00:00.000Z",
"stats": {
"taskCount": 12,
"recomputedCount": 3,
"savedCount": 2,
"durationMs": 39
}
}Remove a dependency
DEL/api/projects/{projectId}/dependencies/{dependencyId}
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
| dependencyId zorunlu | string (uuid) |
Döndürür
200 OK Removed
| Alan | Tür | Açıklama | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tasks | array of Task | Created/updated tasks plus the ones the recalculation moved. | |||||||||||||||
| deletedTaskIds | array of string | ||||||||||||||||
| dependencies | array of Dependency | ||||||||||||||||
| deletedDependencyIds | array of string | ||||||||||||||||
| conflicts | array of Conflict | ||||||||||||||||
| projectStartAt | string (date-time) | ||||||||||||||||
| projectFinishAt | string (date-time) | ||||||||||||||||
| stats | object | stats alanlarını göster
|
curl -X DELETE https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies/9ba5faf8-923d-4ecc-86f0-f245c5d179db \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies/9ba5faf8-923d-4ecc-86f0-f245c5d179db", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(res.status); // 204import os
import requests
res = requests.delete(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/dependencies/9ba5faf8-923d-4ecc-86f0-f245c5d179db",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.status_code) # 204{
"tasks": [
{
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"sortKey": "i",
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null
}
],
"deletedTaskIds": [],
"dependencies": [
{
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
],
"deletedDependencyIds": [],
"conflicts": [],
"projectStartAt": "2026-10-05T06:00:00.000Z",
"projectFinishAt": "2026-10-07T15:00:00.000Z",
"stats": {
"taskCount": 12,
"recomputedCount": 3,
"savedCount": 2,
"durationMs": 39
}
}API başvurusu
People
Project members and task assignees.
Member
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| userId | string (uuid) | |
| name | string | |
| string | ||
| role | string | Effective role on the project. Şunlardan biri: |
| directRole | stringboş olabilir | Role granted on the project itself (null = only through the workspace). Şunlardan biri: |
| inherited | boolean | Access comes from the workspace. |
| resourceId | string (uuid)boş olabilir | Resource used when the person is assigned to tasks. |
| addedAt | string (date-time) | |
| avatarUrl | stringboş olabilir |
{
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"email": "[email protected]",
"role": "owner",
"directRole": null,
"inherited": false,
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"addedAt": "2026-10-01T08:30:12.418Z",
"avatarUrl": null
}Assignee
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| resourceId | string (uuid) | |
| userId | string (uuid)boş olabilir | |
| name | string | |
| unitsPct | integer |
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}Replace the people assigned to a task
PUT/api/projects/{projectId}/tasks/{taskId}/assignees
Yazma erişimli anahtar
userIds must be members of the project (GET /members). An empty list removes everyone. Optional resourceIds replaces the people imported from a file (resources without an account) assigned to the task; omit it to leave them as they are.
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
| taskId zorunlu | string (uuid) | Task id. |
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| userIds zorunlu | array of string | |
| resourceIds | array of string |
Döndürür
200 OK Assignees saved
| Alan | Tür | Açıklama | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| taskId | string (uuid) | |||||||||||||||||||||||||||||||||||||
| assignments | array of object | assignments alanlarını göster
| ||||||||||||||||||||||||||||||||||||
| resources | array of object | resources alanlarını göster
| ||||||||||||||||||||||||||||||||||||
| needsReschedule | boolean | |||||||||||||||||||||||||||||||||||||
| conflicts | array of Conflict |
curl -X PUT https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/assignees \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userIds":["b1666432-132a-4ea9-b1ae-76ea69e226c5"]}'const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/assignees", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
userIds: ["b1666432-132a-4ea9-b1ae-76ea69e226c5"],
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.put(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/tasks/4dbd104a-00cd-4035-8955-255f52ea586a/assignees",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"userIds": ["b1666432-132a-4ea9-b1ae-76ea69e226c5"],
},
)
res.raise_for_status()
print(res.json()){
"taskId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"assignments": [
{
"id": "e62ac96b-e68e-40d3-842e-335e27dfd099",
"taskId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"unitsPct": 100,
"workMin": 0
}
],
"resources": [
{
"id": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"kind": "builtin",
"email": "[email protected]",
"costPerHour": 0,
"costPerUse": 0,
"capacityPct": 0,
"calendarId": null,
"color": null,
"avatarUrl": null
}
],
"needsReschedule": false,
"conflicts": []
}People with access to the project (assignable)
GET/api/projects/{projectId}/members
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| projectId zorunlu | string (uuid) | Project id. |
Döndürür
200 OK Members
| Alan | Tür | Açıklama |
|---|---|---|
| members | array of Member | |
| role | string |
curl https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/members \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/members", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8/members",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"members": [
{
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"email": "[email protected]",
"role": "owner",
"directRole": null,
"inherited": false,
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"addedAt": "2026-10-01T08:30:12.418Z",
"avatarUrl": null
}
],
"role": "owner"
}API başvurusu
Webhooks
Outgoing webhook subscriptions (REST hooks: subscribe/unsubscribe).
- GET/api/webhooks
- POST/api/webhooks
- GET/api/webhooks/events
- GET/api/webhooks/{webhookId}
- PATCH/api/webhooks/{webhookId}
- DELETE/api/webhooks/{webhookId}
- GET/api/webhooks/{webhookId}/deliveries
- GET/api/webhooks/{webhookId}/deliveries/{deliveryId}
- POST/api/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver
- POST/api/webhooks/{webhookId}/test
- POST/api/webhooks/{webhookId}/rotate-secret
Webhook
Öznitelikler
| Alan | Tür | Açıklama | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| id | string (uuid) | ||||||||||
| workspaceId | string (uuid) | ||||||||||
| workspaceName | string | ||||||||||
| projectId | string (uuid)boş olabilir | null = every project of the workspace. | |||||||||
| projectName | stringboş olabilir | ||||||||||
| name | string | ||||||||||
| url | string (uri) | ||||||||||
| events | array of string | Şunlardan biri: | |||||||||
| secretPrefix | string | First characters of the signing secret (not secret). | |||||||||
| active | boolean | ||||||||||
| disabledReason | stringboş olabilir | Şunlardan biri: | |||||||||
| disabledAt | string (date-time)boş olabilir | ||||||||||
| consecutiveFailures | integer | ||||||||||
| viaApi | boolean | Created with the API (REST hook) rather than from the profile. | |||||||||
| createdBy | objectboş olabilir | createdBy alanlarını göster
| |||||||||
| createdAt | string (date-time) | ||||||||||
| updatedAt | string (date-time) | ||||||||||
| lastDeliveryAt | string (date-time)boş olabilir | ||||||||||
| lastSuccessAt | string (date-time)boş olabilir |
{
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"workspaceName": "Acme Construction",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"projectName": "Warehouse expansion",
"name": "Warehouse sync",
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"secretPrefix": "whsec_Fdwl",
"active": true,
"disabledReason": null,
"disabledAt": null,
"consecutiveFailures": 0,
"viaApi": true,
"createdBy": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"lastDeliveryAt": "2026-10-01T08:30:12.418Z",
"lastSuccessAt": "2026-10-01T08:30:12.418Z"
}Delivery
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| eventId | string (uuid) | |
| eventType | string | |
| status | string | Şunlardan biri: |
| attempts | integer | |
| nextAttemptAt | string (date-time)boş olabilir | |
| lastAttemptAt | string (date-time)boş olabilir | |
| responseStatus | integerboş olabilir | |
| responseExcerpt | stringboş olabilir | |
| error | stringboş olabilir | |
| durationMs | integerboş olabilir | |
| manual | boolean | |
| createdAt | string (date-time) |
{
"id": "4b207161-80f9-40bb-bc3f-d8f70315be00",
"eventId": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"eventType": "task.completed",
"status": "success",
"attempts": 1,
"nextAttemptAt": null,
"lastAttemptAt": "2026-10-01T08:30:12.418Z",
"responseStatus": 200,
"responseExcerpt": "{\"ok\":true}",
"error": null,
"durationMs": 39,
"manual": false,
"createdAt": "2026-10-01T08:30:12.418Z"
}Event
Öznitelikler
| Alan | Tür | Açıklama | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| id zorunlu | string (uuid) | Event id, also in the Planitude-Event-Id header: use it to deduplicate. | |||||||||
| type zorunlu | string | Şunlardan biri: | |||||||||
| apiVersion zorunlu | string | Şunlardan biri: | |||||||||
| createdAt zorunlu | string (date-time) | ||||||||||
| workspaceId zorunlu | string (uuid) | ||||||||||
| projectId | string (uuid)boş olabilir | ||||||||||
| actor | objectboş olabilir | Who made the change (null for system changes).actor alanlarını göster
| |||||||||
| data zorunlu | object |
{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "project.created",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {}
}Project (event payload)
Compact project representation used in webhook payloads.
Öznitelikler
| Alan | Tür | Açıklama |
|---|---|---|
| id | string (uuid) | |
| workspaceId | string (uuid) | |
| key | string | |
| name | string | |
| description | stringboş olabilir | |
| startDate | string (date) | |
| deadline | string (date)boş olabilir | |
| currency | string | |
| scheduleFrom | string | Şunlardan biri: |
| color | stringboş olabilir | |
| archived | boolean | |
| createdAt | string (date-time) | |
| updatedAt | string (date-time) | |
| url | string (uri) |
{
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"deadline": null,
"currency": "EUR",
"scheduleFrom": "forward",
"color": null,
"archived": false,
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"url": "https://planitude.app/app/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8"
}List webhook subscriptions
GET/api/webhooks
Okuma erişimli anahtar
Sorgu parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| workspaceId | string (uuid) | |
| projectId | string (uuid) |
Döndürür
200 OK Subscriptions
| Alan | Tür | Açıklama |
|---|---|---|
| webhooks | array of Webhook |
curl https://planitude.app/api/webhooks \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/webhooks",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"webhooks": [
{
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"workspaceName": "Acme Construction",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"projectName": "Warehouse expansion",
"name": "Warehouse sync",
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"secretPrefix": "whsec_Fdwl",
"active": true,
"disabledReason": null,
"disabledAt": null,
"consecutiveFailures": 0,
"viaApi": true,
"createdBy": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"lastDeliveryAt": "2026-10-01T08:30:12.418Z",
"lastSuccessAt": "2026-10-01T08:30:12.418Z"
}
]
}Subscribe (REST hook)
POST/api/webhooks
Yazma erişimli anahtar
Creates a subscription. The response contains the signing secret: it is shown only once. Aliases accepted for automation platforms: targetUrl for url, event for a single event.
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| url zorunlu | string (uri) | HTTPS endpoint that receives the events. Public addresses only. |
| events zorunlu | array of string | * = all events.Şunlardan biri: |
| name | string | |
| projectId | string (uuid) | Limit to one project (editor role needed). Omit for the whole workspace (owner/admin). |
| workspaceId | string (uuid) |
Döndürür
201 Created Created
| Alan | Tür | Açıklama |
|---|---|---|
| webhook | Webhook | |
| secret | string | whsec_... |
curl -X POST https://planitude.app/api/webhooks \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8"
}'const res = await fetch("https://planitude.app/api/webhooks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/hooks/planitude",
events: ["task.created", "task.completed"],
projectId: "40be00e0-7e34-4f7a-864b-5cc986f575b8",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/webhooks",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"url": "https://example.com/hooks/planitude",
"events": ["task.created", "task.completed"],
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
},
)
res.raise_for_status()
print(res.json()){
"webhook": {
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"workspaceName": "Acme Construction",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"projectName": "Warehouse expansion",
"name": "Warehouse sync",
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"secretPrefix": "whsec_Fdwl",
"active": true,
"disabledReason": null,
"disabledAt": null,
"consecutiveFailures": 0,
"viaApi": true,
"createdBy": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"lastDeliveryAt": "2026-10-01T08:30:12.418Z",
"lastSuccessAt": "2026-10-01T08:30:12.418Z"
},
"secret": "whsec_3dvU0T1oaYlW4kH6m2Vb8nqXcR9eZpLsYw1QhGk"
}Event catalog (public)
GET/api/webhooks/events
Herkese açık, anahtarsız
Döndürür
200 OK Events
| Alan | Tür | Açıklama |
|---|---|---|
| apiVersion | string | |
| events | array of string |
curl https://planitude.app/api/webhooks/eventsconst res = await fetch("https://planitude.app/api/webhooks/events");
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import requests
res = requests.get("https://planitude.app/api/webhooks/events")
res.raise_for_status()
print(res.json()){
"apiVersion": "2026-10-01",
"events": [
"project.created",
"project.updated",
"project.deleted",
"task.created",
"task.updated",
"task.deleted",
"task.completed",
"task.dates_changed",
"dependency.created",
"dependency.deleted",
"baseline.saved",
"member.invited",
"member.joined",
"comment.created"
]
}Get a subscription
GET/api/webhooks/{webhookId}
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
Döndürür
200 OK Subscription
| Alan | Tür | Açıklama |
|---|---|---|
| webhook | Webhook |
curl https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88 \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"webhook": {
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"workspaceName": "Acme Construction",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"projectName": "Warehouse expansion",
"name": "Warehouse sync",
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"secretPrefix": "whsec_Fdwl",
"active": true,
"disabledReason": null,
"disabledAt": null,
"consecutiveFailures": 0,
"viaApi": true,
"createdBy": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"lastDeliveryAt": "2026-10-01T08:30:12.418Z",
"lastSuccessAt": "2026-10-01T08:30:12.418Z"
}
}Update, pause or resume a subscription
PATCH/api/webhooks/{webhookId}
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
İstek gövdesi
| Alan | Tür | Açıklama |
|---|---|---|
| name | string | |
| url | string (uri) | |
| events | array of string | |
| active | boolean | false = pause; true = resume (also resets the failure counter). |
Döndürür
200 OK Updated
| Alan | Tür | Açıklama |
|---|---|---|
| webhook | Webhook |
curl -X PATCH https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88 \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"active":false}'const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
active: false,
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.patch(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"active": False,
},
)
res.raise_for_status()
print(res.json()){
"webhook": {
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"workspaceName": "Acme Construction",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"projectName": "Warehouse expansion",
"name": "Warehouse sync",
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"secretPrefix": "whsec_Fdwl",
"active": true,
"disabledReason": null,
"disabledAt": null,
"consecutiveFailures": 0,
"viaApi": true,
"createdBy": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"lastDeliveryAt": "2026-10-01T08:30:12.418Z",
"lastSuccessAt": "2026-10-01T08:30:12.418Z"
}
}Unsubscribe (REST hook)
DEL/api/webhooks/{webhookId}
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
Döndürür
204 No Content Deleted
curl -X DELETE https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88 \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(res.status); // 204import os
import requests
res = requests.delete(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.status_code) # 204Delivery log (newest first, kept 30 days)
GET/api/webhooks/{webhookId}/deliveries
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
Sorgu parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| limit | integer | 1-100. Varsayılan: |
| before | string (date-time) | nextCursor of the previous page. |
Döndürür
200 OK Deliveries
| Alan | Tür | Açıklama |
|---|---|---|
| deliveries | array of Delivery | |
| nextCursor | stringboş olabilir |
curl https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"deliveries": [
{
"id": "4b207161-80f9-40bb-bc3f-d8f70315be00",
"eventId": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"eventType": "task.completed",
"status": "success",
"attempts": 1,
"nextAttemptAt": null,
"lastAttemptAt": "2026-10-01T08:30:12.418Z",
"responseStatus": 200,
"responseExcerpt": "{\"ok\":true}",
"error": null,
"durationMs": 39,
"manual": false,
"createdAt": "2026-10-01T08:30:12.418Z"
}
],
"nextCursor": null
}Body sent with a delivery
GET/api/webhooks/{webhookId}/deliveries/{deliveryId}
Okuma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
| deliveryId zorunlu | string (uuid) |
Döndürür
200 OK Payload
| Alan | Tür | Açıklama |
|---|---|---|
| payload | Event |
curl https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries/4b207161-80f9-40bb-bc3f-d8f70315be00 \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries/4b207161-80f9-40bb-bc3f-d8f70315be00", {
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.get(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries/4b207161-80f9-40bb-bc3f-d8f70315be00",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"payload": {
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "project.created",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {}
}
}Send the same event again
POST/api/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
| deliveryId zorunlu | string (uuid) |
Döndürür
202 Accepted Queued
| Alan | Tür | Açıklama |
|---|---|---|
| delivery | Delivery |
curl -X POST https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries/4b207161-80f9-40bb-bc3f-d8f70315be00/redeliver \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries/4b207161-80f9-40bb-bc3f-d8f70315be00/redeliver", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/deliveries/4b207161-80f9-40bb-bc3f-d8f70315be00/redeliver",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"delivery": {
"id": "4b207161-80f9-40bb-bc3f-d8f70315be00",
"eventId": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"eventType": "task.completed",
"status": "success",
"attempts": 1,
"nextAttemptAt": null,
"lastAttemptAt": "2026-10-01T08:30:12.418Z",
"responseStatus": 200,
"responseExcerpt": "{\"ok\":true}",
"error": null,
"durationMs": 39,
"manual": false,
"createdAt": "2026-10-01T08:30:12.418Z"
}
}Send a webhook.ping test event
POST/api/webhooks/{webhookId}/test
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
Döndürür
202 Accepted Queued
| Alan | Tür | Açıklama |
|---|---|---|
| delivery | Delivery |
curl -X POST https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/test \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/test", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/test",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"delivery": {
"id": "4b207161-80f9-40bb-bc3f-d8f70315be00",
"eventId": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"eventType": "task.completed",
"status": "success",
"attempts": 1,
"nextAttemptAt": null,
"lastAttemptAt": "2026-10-01T08:30:12.418Z",
"responseStatus": 200,
"responseExcerpt": "{\"ok\":true}",
"error": null,
"durationMs": 39,
"manual": false,
"createdAt": "2026-10-01T08:30:12.418Z"
}
}Generate a new signing secret
POST/api/webhooks/{webhookId}/rotate-secret
Yazma erişimli anahtar
Yol parametreleri
| Alan | Tür | Açıklama |
|---|---|---|
| webhookId zorunlu | string (uuid) | Webhook id. |
Döndürür
200 OK New secret (shown once)
| Alan | Tür | Açıklama |
|---|---|---|
| webhook | Webhook | |
| secret | string |
curl -X POST https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/rotate-secret \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/rotate-secret", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/rotate-secret",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"webhook": {
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"workspaceName": "Acme Construction",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"projectName": "Warehouse expansion",
"name": "Warehouse sync",
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"secretPrefix": "whsec_Fdwl",
"active": true,
"disabledReason": null,
"disabledAt": null,
"consecutiveFailures": 0,
"viaApi": true,
"createdBy": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"lastDeliveryAt": "2026-10-01T08:30:12.418Z",
"lastSuccessAt": "2026-10-01T08:30:12.418Z"
},
"secret": "whsec_3dvU0T1oaYlW4kH6m2Vb8nqXcR9eZpLsYw1QhGk"
}Webhook'lar
Webhook'lar
Webhook'lar, değişiklik web uygulamasından, API'den, MCP sunucusundan veya bir içe aktarmadan gelsin, bir şey değiştiği anda uç noktanıza JSON gövdeli bir HTTPS POST gönderir. Bir webhook tek bir projeyi veya bir çalışma alanının tüm projelerini (sahipler ve yöneticiler) kapsar.
Bunları Profil → Webhook'lar bölümünde veya REST hook'ları olarak API ile oluşturun: POST /api/webhooks ile abone olun, DELETE ile abonelikten çıkın. İmzalama gizli anahtarı yalnızca bir kez gösterilir.
Her istek şu üst bilgileri taşır:
| Üst bilgi | Açıklama |
|---|---|
| Planitude-Signature | t=<unix seconds>,v1=<hex HMAC-SHA256>: see Verify signatures. |
| Planitude-Event | Event type, e.g. task.completed. |
| Planitude-Event-Id | Event id, the same in every retry: use it to deduplicate. |
| Planitude-Delivery | Id of this delivery (changes with a manual resend). |
| User-Agent | Planitude-Webhooks/1.0 (+https://planitude.app/developers) |
| Content-Type | application/json |
curl -X POST https://planitude.app/api/webhooks \
-H "Authorization: Bearer $PLANITUDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8"
}'const res = await fetch("https://planitude.app/api/webhooks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/hooks/planitude",
events: ["task.created", "task.completed"],
projectId: "40be00e0-7e34-4f7a-864b-5cc986f575b8",
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/webhooks",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
json={
"url": "https://example.com/hooks/planitude",
"events": ["task.created", "task.completed"],
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
},
)
res.raise_for_status()
print(res.json()){
"webhook": {
"id": "1747ee7f-a395-4d3c-94b0-54b513d71d88",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"workspaceName": "Acme Construction",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"projectName": "Warehouse expansion",
"name": "Warehouse sync",
"url": "https://example.com/hooks/planitude",
"events": [
"task.created",
"task.completed"
],
"secretPrefix": "whsec_Fdwl",
"active": true,
"disabledReason": null,
"disabledAt": null,
"consecutiveFailures": 0,
"viaApi": true,
"createdBy": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"lastDeliveryAt": "2026-10-01T08:30:12.418Z",
"lastSuccessAt": "2026-10-01T08:30:12.418Z"
},
"secret": "whsec_3dvU0T1oaYlW4kH6m2Vb8nqXcR9eZpLsYw1QhGk"
}Olay türleri
Tek tek olaylara veya hepsi için * değerine abone olun. Her olay aynı zarfa sahiptir; data türe göre değişir.
| Olay | Açıklama |
|---|---|
| project.created | A project was created (blank, from a template, duplicated or imported from MS Project). |
| project.updated | Project fields changed (name, dates, deadline, archive...), or a saved version was restored. |
| project.deleted | A project was deleted. |
| task.created | A task was created. |
| task.updated | Task fields or assignees changed. changes lists only the fields that changed. |
| task.deleted | A task was deleted (one event per task of a deleted branch). |
| task.completed | Task progress reached 100%. |
| task.dates_changed | Start or finish moved, because of an edit (cause: edit) or because the schedule was recalculated (cause: reschedule). |
| dependency.created | A dependency was created or changed. |
| dependency.deleted | A dependency was removed. |
| baseline.saved | A baseline was saved. |
| member.invited | An invite link was created for the project. |
| member.joined | A person joined the project. |
| comment.created | A comment was added to a task. |
{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "project.created",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"project": {
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"deadline": null,
"currency": "EUR",
"scheduleFrom": "forward",
"color": null,
"archived": false,
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"url": "https://planitude.app/app/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8"
},
"source": "blank"
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "project.updated",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"project": {
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"deadline": null,
"currency": "EUR",
"scheduleFrom": "forward",
"color": null,
"archived": false,
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"url": "https://planitude.app/app/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8"
},
"changes": {
"deadline": {
"from": null,
"to": "2026-12-18"
}
},
"reason": "version_restored"
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "project.deleted",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"project": {
"id": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"key": "WHX",
"name": "Warehouse expansion",
"description": null,
"startDate": "2026-10-05",
"deadline": null,
"currency": "EUR",
"scheduleFrom": "forward",
"color": null,
"archived": false,
"createdAt": "2026-10-01T08:30:12.418Z",
"updatedAt": "2026-10-01T08:30:12.418Z",
"url": "https://planitude.app/app/projects/40be00e0-7e34-4f7a-864b-5cc986f575b8"
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "task.created",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"task": {
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "task.updated",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"task": {
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
},
"changes": {
"progressPct": {
"from": 40,
"to": 60
}
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "task.deleted",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"task": {
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "task.completed",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"task": {
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 100,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": true,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "task.dates_changed",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"task": {
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
},
"cause": "reschedule",
"changes": {
"startAt": {
"from": "2026-10-02T06:00:00.000Z",
"to": "2026-10-05T06:00:00.000Z"
},
"finishAt": {
"from": "2026-10-06T15:00:00.000Z",
"to": "2026-10-07T15:00:00.000Z"
}
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "dependency.created",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"dependency": {
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "dependency.deleted",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"dependency": {
"id": "9ba5faf8-923d-4ecc-86f0-f245c5d179db",
"predecessorId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"successorId": "a22fd799-c4dc-4869-a466-0dd6e96f71ce",
"type": "FS",
"lagMin": 0
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "baseline.saved",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"baseline": {
"id": "b5d68d05-0640-48f9-8eeb-ed7804f4a116",
"name": "Plan v1",
"index": null,
"capturedAt": "2026-10-01T08:30:12.418Z",
"capturedBy": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"taskCount": 12
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "member.invited",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"invite": {
"id": "5d0b7c11-8e2a-4f63-a1d4-93c7e2b6f804",
"role": "editor",
"expiresAt": "2026-10-31T08:30:12.418Z",
"maxUses": null
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "member.joined",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"member": {
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"role": "editor"
}
}
}{
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"type": "comment.created",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-01T08:30:12.418Z",
"workspaceId": "824650d2-d0b3-4cac-8df8-5743ae9ff65a",
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"actor": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"data": {
"comment": {
"id": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"taskId": "4dbd104a-00cd-4035-8955-255f52ea586a",
"body": "Concrete delivered, we can start the walls.",
"author": {
"id": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi"
},
"createdAt": "2026-10-01T08:30:12.418Z"
},
"task": {
"id": "4dbd104a-00cd-4035-8955-255f52ea586a",
"number": 1,
"key": "WHX-1",
"parentId": null,
"name": "Foundations",
"type": "task",
"durationMin": 1440,
"workMin": 0,
"progressPct": 0,
"constraintKind": "asap",
"constraintDate": null,
"deadline": null,
"calendarId": null,
"costFixed": 0,
"notes": null,
"color": null,
"wbs": null,
"externalId": "crm-4711",
"startAt": "2026-10-05T06:00:00.000Z",
"finishAt": "2026-10-07T15:00:00.000Z",
"isCritical": true,
"totalFloatMin": 0,
"earlyStartAt": "2026-10-05T06:00:00.000Z",
"lateFinishAt": "2026-10-07T15:00:00.000Z",
"actualStartAt": null,
"actualFinishAt": null,
"actualDurationMin": null,
"remainingDurationMin": null,
"manuallyScheduled": false,
"levelingDelayMin": 0,
"taskType": "fixed_units",
"effortDriven": false,
"durationOptimisticMin": null,
"durationPessimisticMin": null,
"projectId": "40be00e0-7e34-4f7a-864b-5cc986f575b8",
"completed": false,
"assignees": [
{
"resourceId": "0c6a8f52-3d7e-4b19-9a4e-6f1d2c8b7e30",
"userId": "b1666432-132a-4ea9-b1ae-76ea69e226c5",
"name": "Anna Rossi",
"unitsPct": 100
}
],
"url": "https://planitude.app/app/t/WHX-1"
}
}
}İmzaları doğrulama
Her istek, HMAC-SHA256 ve webhook'unuzun gizli anahtarıyla imzalanır. Planitude-Signature üst bilgisi bir t zaman damgası ve t, bir nokta ve ham gövde üzerinde hesaplanan v1 imzasını içerir.
- Ham gövdeyi, herhangi bir JSON ayrıştırmasından önce kullanın: yeniden serileştirilmiş bir gövdenin imzası farklıdır.
- HMAC'i hesaplayın ve sabit zamanlı karşılaştırın.
- Zaman damgası saatinizden 5 dakikadan fazla sapan istekleri reddedin: yakalanan bir istek yeniden oynatılamaz.
- Gizli anahtarı istediğiniz zaman yenileyin: eskisi anında çalışmaz hale gelir.
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body as a string, before JSON.parse
export function verifyPlanitude(rawBody, header, secret, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false; // replay
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
const given = Buffer.from(parts.v1 ?? "", "hex");
return given.length === expected.length && timingSafeEqual(given, expected);
}
// Express: app.post("/hooks/planitude", express.raw({ type: "application/json" }), (req, res) => {
// if (!verifyPlanitude(req.body.toString("utf8"), req.get("Planitude-Signature"), process.env.PLANITUDE_WEBHOOK_SECRET)) return res.sendStatus(400);
// res.sendStatus(200); // then process the event in a queue
// });import hashlib
import hmac
import time
def verify_planitude(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts.get("t", "0"))
if abs(time.time() - t) > tolerance:
return False # replay
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))
# Flask: verify_planitude(request.get_data(), request.headers["Planitude-Signature"], os.environ["PLANITUDE_WEBHOOK_SECRET"])Yeniden denemeler ve teslimat
10 saniye içinde herhangi bir 2xx ile yanıt verin ve asıl işi sonra, bir kuyrukta yapın. Yönlendirmeler izlenmez. Hata ve zaman aşımlarında Planitude toplam 6 kez dener: hemen, ardından 1 min, 5 min, 30 min, 2 h, 12 h sonra.
Teslimat en az bir kez yapılır ve sıralı değildir. Olay kimliğini (Planitude-Event-Id, gövdede id) saklayın ve zaten işlediklerinizi atlayın; createdAt ile sıralayın.
Art arda 5 olay tüm denemelerde başarısız olursa webhook devre dışı bırakılır ve sahibi bir e-posta alır. 410 Gone yanıtı onu hemen devre dışı bırakır. Profilden veya PATCH ile active: true göndererek yeniden açın.
Teslimat günlüğü (durum, HTTP kodu, yanıt özeti, yük, elle yeniden gönderme) 30 gün saklanır. Hedef olarak yalnızca herkese açık adresler kabul edilir.
Deneme 1 hemen
Deneme 2 + 1 min
Deneme 3 + 5 min
Deneme 4 + 30 min
Deneme 5 + 2 h
Deneme 6 + 12 hUç noktanızı test edin
- Test uç noktasıyla veya profildeki Test düğmesiyle bir
webhook.pingolayı gönderin. - Olayları bilgisayarınızda almak için yerel sunucunuzu bir tünelle (örneğin ngrok veya Cloudflare Tunnel) dışarı açın ve herkese açık HTTPS adresini abone edin.
- Durumu, HTTP kodunu ve yanıtı görmek için teslimat günlüğünü açın; uç noktanız düzeldikten sonra bir teslimatı yeniden gönderin.
curl -X POST https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/test \
-H "Authorization: Bearer $PLANITUDE_API_KEY"const res = await fetch("https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/test", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLANITUDE_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());import os
import requests
res = requests.post(
"https://planitude.app/api/webhooks/1747ee7f-a395-4d3c-94b0-54b513d71d88/test",
headers={"Authorization": f"Bearer {os.environ['PLANITUDE_API_KEY']}"},
)
res.raise_for_status()
print(res.json()){
"delivery": {
"id": "4b207161-80f9-40bb-bc3f-d8f70315be00",
"eventId": "6f1c1d1e-2f4b-4d0a-9a77-2a3c5b1e9f10",
"eventType": "task.completed",
"status": "success",
"attempts": 1,
"nextAttemptAt": null,
"lastAttemptAt": "2026-10-01T08:30:12.418Z",
"responseStatus": 200,
"responseExcerpt": "{\"ok\":true}",
"error": null,
"durationMs": 39,
"manual": false,
"createdAt": "2026-10-01T08:30:12.418Z"
}
}Yapay zekâ ve MCP
MCP sunucusu
Planitude bir MCP (Model Context Protocol) sunucusudur: yapay zekâ asistanları ve kod düzenleyicileri, izinlerinizle projeleri okur, kritik yolu ve iş yükünü analiz eder, görevler oluşturur veya değiştirir. Web uygulamaları OAuth ile bağlanır (oturum açar ve erişime izin verirsiniz); komut satırı araçları ve düzenleyiciler bir API anahtarı kullanır.
Sunucu URL'si
https://planitude.app/mcp
- ChatGPTOAuth
ChatGPT'de Ayarlar › Güvenlik ve oturum açma bölümünü açın ve Geliştirici modunu etkinleştirin. Sunucu URL'si ve OAuth kimlik doğrulamasıyla bir uygulama oluşturun, ardından Planitude'da oturum açıp erişime izin verin.
Resmî belgeler ↗ - ClaudeOAuth
Özelleştir › Bağlayıcılar › Özel bağlayıcı ekle bölümünü açın, sunucu URL'sini yapıştırın ve Bağlan'ı seçin: Planitude açılır, oturum açar ve erişime izin verirsiniz. claude.ai'de, Claude Desktop'ta ve mobil uygulamada çalışır.
Resmî belgeler ↗ - GeminiOAuth
gemini.google.com'da Ayarlar › Bağlı uygulamalar bölümünü açın, Özel uygulama ekle'yi seçin ve sunucu URL'sini yapıştırın; ardından Planitude'da oturum açıp erişime izin verin.
Resmî belgeler ↗ - Claude CodeAPI anahtarı
Komutu anahtarınızı bir ortam değişkeninde vererek çalıştırın. Her projede kullanmak için
Resmî belgeler ↗--scope userekleyin veclaude mcp listile kontrol edin. - CodexAPI anahtarı
Anahtarı
Resmî belgeler ↗PLANITUDE_API_KEYiçine koyun ve bloğu~/.codex/config.tomldosyasına ekleyin: CLI, uygulama ve IDE eklentisi için geçerlidir. - CursorAPI anahtarı
Bloğu
Resmî belgeler ↗~/.cursor/mcp.json(tüm projeler) veya.cursor/mcp.json(tek proje) dosyasına ekleyin; Cursor anahtarı ortamdan okur. - Visual Studio CodeAPI anahtarı
Çalışma alanına
Resmî belgeler ↗.vscode/mcp.jsonekleyin: VS Code anahtarı bir kez ister ve dosyanın dışında güvenli biçimde saklar. - Gemini CLIAPI anahtarı
Komutu anahtarınızı bir ortam değişkeninde vererek çalıştırın veya bloğu
Resmî belgeler ↗~/.gemini/settings.jsondosyasına ekleyin.
Araçlar
Sunucu, okuma ve analizden güvenli değişikliklere kadar 29 araç sunar. Hiçbiri proje veya görev silmez.
read
planitude_list_projectsplanitude_portfolio_overviewplanitude_get_projectplanitude_critical_pathplanitude_delay_impactplanitude_monte_carloplanitude_workloadplanitude_list_baselinesplanitude_list_versionsplanitude_list_templatesplanitude_list_commentsplanitude_preview_import
write
planitude_create_projectplanitude_create_project_from_templateplanitude_create_project_from_planplanitude_import_fileplanitude_edit_projectplanitude_add_taskplanitude_update_taskplanitude_set_progressplanitude_indent_taskplanitude_outdent_taskplanitude_link_tasksplanitude_unlink_tasksplanitude_rescheduleplanitude_configure_simulationplanitude_add_commentplanitude_save_baselineplanitude_save_version
Server URL
https://planitude.app/mcpServer URL
https://planitude.app/mcpServer URL
https://planitude.app/mcpTerminal
claude mcp add --transport http planitude https://planitude.app/mcp \
--header "Authorization: Bearer $PLANITUDE_API_KEY"~/.codex/config.toml
[mcp_servers.planitude]
url = "https://planitude.app/mcp"
bearer_token_env_var = "PLANITUDE_API_KEY"~/.cursor/mcp.json
{
"mcpServers": {
"planitude": {
"url": "https://planitude.app/mcp",
"headers": {
"Authorization": "Bearer ${env:PLANITUDE_API_KEY}"
}
}
}
}.vscode/mcp.json
{
"servers": {
"planitude": {
"type": "http",
"url": "https://planitude.app/mcp",
"headers": {
"Authorization": "Bearer ${input:planitude-key}"
}
}
},
"inputs": [
{
"id": "planitude-key",
"type": "promptString",
"description": "Planitude API key",
"password": true
}
]
}Terminal
gemini mcp add --transport http \
--header "Authorization: Bearer $PLANITUDE_API_KEY" planitude https://planitude.app/mcp~/.gemini/settings.json
{
"mcpServers": {
"planitude": {
"httpUrl": "https://planitude.app/mcp",
"headers": {
"Authorization": "Bearer $PLANITUDE_API_KEY"
}
}
}
}Hazır entegrasyonlar
Kod gerekmez: bu entegrasyonlar aynı API'yi ve webhook'ları kullanır ve birkaç tıkla kurulur.
- JiraKullanılabilirGörevlerin, tarihlerin ve bağımlılıkların Jira iş öğeleriyle iki yönlü eşitlenmesi.
- Azure DevOpsKullanılabilirAzure DevOps Boards iş öğeleriyle iki yönlü eşitleme.
- SlackKullanılabilirKanallarınızda proje güncellemeleri, günlük özetler ve bir eğik çizgi komutu.
- Microsoft TeamsKullanılabilirMicrosoft Teams'te güncellemeler, özetler ve bir Planitude sekmesi.
- Zapier, Make, n8nYakındaKodsuz otomasyonlar için görevler ve projeler üzerinde anlık tetikleyiciler ve eylemler.
Değişiklik günlüğü
OpenAPI belgesinden üretilen yeni geliştirici belgeleri. OpenAPI belgesi artık üyeler, yorumlar, temel planlar, şablonlar ve atananlar için döndürülen her alanı tanımlıyor.
API sürümü 2026-10-01: imzalı giden webhook'lar, belgelenmiş herkese açık REST API (OpenAPI 3.1), imleç sayfalama ve externalId ile arama.
MCP sunucusu ve API için OAuth 2.1: ChatGPT, Claude ve Gemini, anahtar kopyalamadan bağlanır.
MCP sunucusu ve okuma veya okuma + yazma erişimli kişisel API anahtarları.