Projekt Developers
5 minutes

Quickstart.

Mint a Personal Access Token, send your first authenticated request, list the issues in one of your projects, and create a new one. Once you have done this loop once, the rest of the API is just more of the same.

Prerequisites#

1. Mint a key#

Keys live inside the org they unlock. Open Projekt, go to Organization → Settings → General → Integraciones, and click Create API key.

You will see the plaintext token exactly once. Copy it now into a secret manager — Projekt only stores its SHA-256 hash, so a lost key cannot be recovered, only revoked and replaced.

pjk_live_AbCd1234EfGh5678IjKl9012MnOp3456
i
Token format

All tokens start with pjk_live_ followed by 32 base62 characters (~190 bits of entropy). The prefix lets secret scanners spot leaks; the rest is the actual secret.

2. Call /me#

The cheapest way to confirm a token is alive is to hit /me:

curl https://projekt.3xa.es/api/me \
  -H "Authorization: Bearer pjk_live_..."

You should get a JSON document describing the user the key belongs to:

{
  "id": "ad8c…",
  "email": "you@example.com",
  "name": "You",
  "username": "you",
  "locale": "es"
}

3. List your orgs#

Even though a PAT is bound to a single org, /me/orgs is a friendly way to grab the org_id you need for the rest of the calls.

curl https://projekt.3xa.es/api/me/orgs \
  -H "Authorization: Bearer pjk_live_..."
{
  "orgs": [
    {
      "employee_id": "…",
      "org_id":   "9f1c…",
      "org_name": "Acme Inc",
      "org_slug": "acme",
      "role":     "owner",
      "projects": [
        { "id": "…", "name": "Website redesign", "key": "WEB" }
      ]
    }
  ],
  "count": 1
}

Keep org_id handy — most endpoints want it in the X-Org-Id header.

4. List the issues in a project#

curl "https://projekt.3xa.es/api/issues?project_id=<PROJECT_ID>" \
  -H "Authorization: Bearer pjk_live_..." \
  -H "X-Org-Id: <ORG_ID>"
[
  {
    "id":        "…",
    "title":     "Fix login bug",
    "status":    "In Progress",
    "priority":  "high",
    "assignee_id": "ad8c…"
  }
]

5. Create an issue#

curl -X POST https://projekt.3xa.es/api/issues \
  -H "Authorization: Bearer pjk_live_..." \
  -H "X-Org-Id: <ORG_ID>" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "<PROJECT_ID>",
    "title":      "Investigate flaky CI test",
    "status":     "Backlog",
    "priority":   "medium",
    "description": "The auth e2e test fails 1 in 5 runs."
  }'
{
  "id":        "…",
  "title":     "Investigate flaky CI test",
  "status":    "Backlog",
  "priority":  "medium",
  "project_id": "…",
  "created_at": "2026-05-28T09:14:02Z"
}

From other languages#

Python#

import os, requests

TOKEN  = os.environ["PROJEKT_API_KEY"]
ORG_ID = os.environ["PROJEKT_ORG_ID"]

resp = requests.get(
    "https://projekt.3xa.es/api/issues",
    params={"project_id": "..."},
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "X-Org-Id":      ORG_ID,
    },
    timeout=15,
)
resp.raise_for_status()
for issue in resp.json():
    print(issue["title"])

Node.js / TypeScript#

const res = await fetch("https://projekt.3xa.es/api/issues?project_id=...", {
  headers: {
    Authorization: `Bearer ${process.env.PROJEKT_API_KEY}`,
    "X-Org-Id":    process.env.PROJEKT_ORG_ID!,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const issues: Array<{ id: string; title: string }> = await res.json();

PHP#

<?php
$ch = curl_init("https://projekt.3xa.es/api/issues?project_id=...");
curl_setopt_array($ch, [
  CURLOPT_HTTPHEADER     => [
    "Authorization: Bearer " . getenv("PROJEKT_API_KEY"),
    "X-Org-Id: "             . getenv("PROJEKT_ORG_ID"),
  ],
  CURLOPT_RETURNTRANSFER => true,
]);
$issues = json_decode(curl_exec($ch), true);

Where to go next#