# Setup

> This skill should be used when the user wants to "connect to Taiga", "log into Taiga", "authenticate with Taiga", "get a Taiga auth token", "set up Taiga access", or before running any Taiga REST API call. Establishes the auth token and the global request conventions (headers, pagination, version locking, the resolver).

- Skill: `agents-store/setup-4` (Agent Skill)
- Install (CLI): `npx skillmds@latest add agents-store/setup-4`
- Raw SKILL.md: https://api.skillmd.com/api/skills/agents-store/setup-4/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: agents-store (https://skillmd.com/u/agents-store)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/agents-store/setup-4

---


# Taiga Setup & Authentication

Establish access to a Taiga instance and learn the conventions every other call depends on. Do this once per session before any other Taiga operation.

## Environment variables

The user sets these in their shell or repo `.env`. Read them — never hardcode credentials.

| Variable | Required | Meaning |
|----------|----------|---------|
| `TAIGA_API_URL` | yes | Base instance URL, e.g. `https://api.taiga.io` (hosted) or `https://taiga.mycompany.com` (self-hosted). The API lives under `${TAIGA_API_URL}/api/v1`. |
| `TAIGA_ADMIN_USERNAME` | yes | Username or email used to obtain a token. |
| `TAIGA_ADMIN_PASSWORD` | yes | Password for that account. |
| `TAIGA_AUTH_TOKEN` | derived | Obtained at runtime from the login call below; reused for the rest of the session. |

If `TAIGA_API_URL` is missing, ask the user for it. If it does not already end without a trailing slash, normalize it (`${TAIGA_API_URL%/}`).

## Step 1 — Obtain the auth token

Taiga issues a JWT from username + password via the `normal` login type. The `type` field is mandatory — omitting it is the most common login failure.

```bash
# Log in and capture both the auth token and the refresh token.
RESP=$(curl -s -X POST "${TAIGA_API_URL%/}/api/v1/auth" \
  -H "Content-Type: application/json" \
  -d "{\"type\":\"normal\",\"username\":\"${TAIGA_ADMIN_USERNAME}\",\"password\":\"${TAIGA_ADMIN_PASSWORD}\"}")

export TAIGA_AUTH_TOKEN=$(echo "$RESP" | jq -r '.auth_token')
export TAIGA_REFRESH=$(echo "$RESP" | jq -r '.refresh')
echo "Logged in as $(echo "$RESP" | jq -r '.username') (id $(echo "$RESP" | jq -r '.id'))"
```

The response also contains `id`, `username`, `full_name`, `email`, `is_superuser`, and more. Keep `TAIGA_AUTH_TOKEN` for all subsequent requests.

## Step 2 — Verify access

```bash
curl -s -H "Authorization: Bearer ${TAIGA_AUTH_TOKEN}" \
  "${TAIGA_API_URL%/}/api/v1/users/me" | jq '{id, username, full_name}'
```

A `200` with your user object confirms the token works.

## Refreshing the token

Auth tokens expire. When a call returns `401`, refresh instead of re-logging in:

```bash
export TAIGA_AUTH_TOKEN=$(curl -s -X POST "${TAIGA_API_URL%/}/api/v1/auth/refresh" \
  -H "Content-Type: application/json" \
  -d "{\"refresh\":\"${TAIGA_REFRESH}\"}" | jq -r '.auth_token')
```

## Application tokens (for external/long-lived integrations)

For unattended integrations, Taiga supports application tokens instead of password login. These use a different header — `Authorization: Application <token>` rather than `Bearer`. The flow is `POST /api/v1/application-tokens/authorize` → `POST /api/v1/application-tokens/validate` → decipher the JWE. See `api-reference` → `references/auth-users.md`. For interactive ops, the username/password flow above is simpler and preferred.

## Global conventions (apply to every call)

These rules hold across the entire API. Internalize them now so individual operations stay short.

- **Base path**: every endpoint is `${TAIGA_API_URL%/}/api/v1/...`.
- **Headers**: send `Authorization: Bearer ${TAIGA_AUTH_TOKEN}` on authenticated calls and `Content-Type: application/json` on any request with a body.
- **Optimistic locking (`version`)**: editing an object (`PATCH`/`PUT` on stories, tasks, issues, epics, milestones, wiki, statuses, attachments, custom-attribute values) **requires the object's current `version`**. Always `GET` the object first, read `.version`, and include it in the body. A `400` complaining about version means the object changed — re-`GET` and retry. This prevents silently overwriting someone else's edit.
- **PATCH vs PUT**: use `PATCH` with only the changed fields (plus `version`) for partial edits. Reserve `PUT` for full-object replacement.
- **Pagination**: list endpoints paginate by default. Read the response headers — `x-pagination-count` (total), `x-pagination-current`, `x-paginated-by` (page size), `x-pagination-next` / `x-pagination-prev` (page URLs). Pass `?page=N` to walk pages, or send the header `x-disable-pagination: True` to fetch everything in one response (use sparingly on large projects). Use `-D -` with curl to inspect headers.
- **Filtering**: list endpoints accept resource filters — commonly `?project=`, `?milestone=`, `?status=`, `?assigned_to=`, `?user_story=` (tasks). Each work-item type also exposes `GET .../filters_data?project=<id>` describing the available filter values.
- **Slugs vs IDs (`/resolver`)**: the API works with numeric IDs, but humans use slugs and references (`#42`). Convert with one call:

```bash
curl -s -H "Authorization: Bearer ${TAIGA_AUTH_TOKEN}" \
  "${TAIGA_API_URL%/}/api/v1/resolver?project=my-project-slug&us=42" | jq .
# -> {"project": 7, "us": 1234}
```

- **i18n**: add `Accept-Language: <locale>` to localize server messages.

## Next steps

- For everyday workflows (create a sprint, add a story, triage an issue, build a report) → use the `common-operations` skill.
- For the full endpoint catalog of every resource → load the `api-reference` skill and open the relevant `references/*.md` file.
- When a call fails → use the `troubleshoot` skill.

