KaitenSDK

1.7.0

AllDmeat/kaiten-sdk

What's New

1.7.0

2026-03-26T21:46:06Z

What's Changed

  • chore(deps): bump github.com/apple/swift-openapi-generator from 1.10.4 to 1.11.0 by @dependabot[bot] in #376
  • Make transport init public by @AllDmeat in #377
  • perf: make DateFormatter static in RetryMiddleware (#369) by @AllDmeat in #378
  • docs: add pagination, filters, and option structs to README by @AllDmeat in #379
  • chore(deps): bump jdx/mise-action from 3 to 4 by @dependabot[bot] in #373
  • chore(deps): bump compnerd/gha-setup-swift from 0.3.0 to 0.4.0 by @dependabot[bot] in #374
  • fix: add unknown case to all SDK enums for forward compatibility (#364) by @AllDmeat in #382
  • docs: clarify isEmptyBody catch block and RetryMiddleware idempotency by @AllDmeat in #383
  • chore(deps): bump github.com/apple/swift-argument-parser from 1.7.0 to 1.7.1 by @dependabot[bot] in #375
  • fix: preserve response body in serverError after retry exhaustion by @AllDmeat in #380
  • feat: centralized rate-limit gate for 429 handling (#342) by @AllDmeat in #381

Full Changelog: 1.6.0...1.7.0

kaiten-sdk

Build

Swift SDK for the Kaiten project management API. OpenAPI-generated types with typed errors, automatic retry on 429 Too Many Requests, and Bearer token authentication.

Full Kaiten API documentation: developers.kaiten.ru

Installation

As a library

Add KaitenSDK to your Package.swift:

dependencies: [
    .package(url: "https://github.com/AllDmeat/kaiten-sdk.git", from: "0.1.0"),
],
targets: [
    .target(
        name: "YourTarget",
        dependencies: [
            .product(name: "KaitenSDK", package: "KaitenSDK"),
        ]
    ),
]

mise (recommended)

mise — a tool version manager. It will install the required version automatically:

mise use github:alldmeat/kaiten-sdk

GitHub Release

Download the binary for your platform from the releases page.

Windows: the archive includes the Swift runtime DLLs — no additional installation required. Extract and run kaiten.exe directly.

Quick Start

As a library

import KaitenSDK

let client = try KaitenClient(
    baseURL: "https://your-company.kaiten.ru/api/latest",
    token: "your-api-token"
)

let spaces = try await client.listSpaces()
let cards = try await client.listCards(boardId: 42)
let card = try await client.getCard(id: 123)

As a CLI

The CLI resolves credentials in order: flags → config file.

1. Get a Kaiten API Token

Get your API token at https://<your-company>.kaiten.ru/profile/api-key.

2. Configure Credentials

Option 1 — Config file (recommended):

Create ~/.config/kaiten/config.json:

{
  "url": "https://<your-company>.kaiten.ru/api/latest",
  "token": "<your-api-token>"
}

Then run commands:

kaiten list-spaces
kaiten get-card --id 123

API Reference

Cards

Method Description
listCards(boardId:) List all cards on a board
getCard(id:) Fetch a single card by ID
createCard(...) Create a new card
updateCard(...) Update a card
deleteCard(...) Delete a card
listCardChildren(...) List child cards
addCardChild(...) Add a child card
removeCardChild(...) Remove a child card
getCardMembers(cardId:) Get members of a card
addCardMember(...) Add a member to a card
updateCardMemberRole(...) Update a card member's role
removeCardMember(...) Remove a member from a card
getCardComments(cardId:) Get comments on a card
createComment(cardId:text:) Add a comment to a card
updateComment(...) Update a comment
deleteComment(...) Delete a comment
listCardTags(...) List tags on a card
addCardTag(...) Add a tag to a card
removeCardTag(...) Remove a tag from a card
listCardBlockers(...) List card blockers
createCardBlocker(...) Create a card blocker
updateCardBlocker(...) Update a card blocker
deleteCardBlocker(...) Delete a card blocker
getCardLocationHistory(...) Get card location history
getCardBaselines(...) Get card baselines

Checklists

Method Description
createChecklist(...) Create a checklist on a card
getChecklist(...) Get a checklist
updateChecklist(...) Update a checklist
removeChecklist(...) Remove a checklist
createChecklistItem(...) Create a checklist item
updateChecklistItem(...) Update a checklist item
removeChecklistItem(...) Remove a checklist item

External Links

Method Description
listExternalLinks(...) List external links on a card
createExternalLink(...) Create an external link
updateExternalLink(...) Update an external link
removeExternalLink(...) Remove an external link

Spaces

Method Description
listSpaces() List all spaces
createSpace(...) Create a space
getSpace(...) Get a space by ID
updateSpace(...) Update a space

Boards

Method Description
listBoards(spaceId:) List boards in a space
getBoard(id:) Fetch a board by ID
createBoard(...) Create a board
updateBoard(...) Update a board

Columns

Method Description
getBoardColumns(boardId:) Get columns for a board
createColumn(...) Create a column
updateColumn(...) Update a column
deleteColumn(...) Delete a column
listSubcolumns(...) List subcolumns
createSubcolumn(...) Create a subcolumn
updateSubcolumn(...) Update a subcolumn
deleteSubcolumn(...) Delete a subcolumn

Lanes

Method Description
getBoardLanes(boardId:) Get lanes for a board
createLane(...) Create a lane
updateLane(...) Update a lane

Custom Properties

Method Description
listCustomProperties() List all custom property definitions
getCustomProperty(id:) Get a single custom property definition
listCustomPropertySelectValues(propertyId:) List select values for a custom property
getCustomPropertySelectValue(propertyId:id:) Get a single select value

Users

Method Description
listUsers() List all users
getCurrentUser() Get the current user

Card Types & Sprints

Method Description
listCardTypes() List card types
listSprints() List sprints
getSprintSummary(...) Get sprint summary

Pagination

Most list endpoints accept offset and limit parameters and return a Page<T>:

let page = try await client.listCards(boardId: 42, offset: 0, limit: 20)
print(page.items)   // [Card] — the items in this page
print(page.hasMore) // true if more pages are available

To fetch the next page, increment offset by limit and repeat until hasMore is false.

Auto-pagination

Convenience methods handle pagination automatically and return an AsyncThrowingStream so you can iterate all items without managing offsets:

for try await card in client.allCards(boardId: 42) {
    print(card.title)
}

Available auto-pagination methods:

Method Description
allCards(boardId:columnId:laneId:filter:pageSize:) All cards matching the given criteria
allUsers(type:query:includeInactive:pageSize:) All users
allCustomProperties(query:pageSize:) All custom property definitions
allCustomPropertySelectValues(propertyId:pageSize:) All select values for a property
allCardTypes(pageSize:) All card types
allSprints(active:pageSize:) All sprints

Each method accepts an optional pageSize parameter (default 100).

Filtering Cards

Use CardFilter to narrow results when listing cards. All properties are optional — set only the ones you need:

let overdueCards = try await client.listCards(
    filter: CardFilter(memberIds: "10,25", overdue: true)
)

Search by text within a space:

let results = try await client.listCards(
    filter: CardFilter(query: "login bug", spaceId: 42)
)

Filters work with auto-pagination too:

let filter = CardFilter(states: [.inProgress], orderBy: "updated_at")
for try await card in client.allCards(boardId: 1, filter: filter) {
    print(card.title)
}

Commonly used filter properties include query, memberIds, states, overdue, spaceId, typeId, condition, and date ranges like createdAfter/createdBefore. See CardFilter source for the full list of 40+ parameters.

Creating & Updating Cards

CardCreateOptions

Create a card by providing a title and board ID. Set additional properties as needed:

var opts = CardCreateOptions(title: "Bug fix", boardId: 1)
opts.columnId = 42
opts.description = "Fix the login crash"
let card = try await client.createCard(opts)

CardUpdateOptions

Update specific fields on an existing card — only the properties you set are sent to the server:

var opts = CardUpdateOptions()
opts.title = "Updated Title"
opts.columnId = 42
let card = try await client.updateCard(id: 123, opts)

Configuration

The CLI and MCP server share the same config file at ~/.config/kaiten/config.json (see Configure Credentials above).

Use --config to provide a custom config file path when needed.

Error Handling

All methods throw KaitenError, which provides typed cases for every failure mode:

do {
    let card = try await client.getCard(id: 999)
} catch let error as KaitenError {
    switch error {
    case .missingConfiguration(let key):
        print("Missing config: \(key)")
    case .invalidURL(let url):
        print("Bad URL: \(url)")
    case .unauthorized:
        print("Check your API token")
    case .notFound(let resource, let id):
        print("\(resource) \(id) not found")
    case .rateLimited(let retryAfter):
        print("Rate limited, retry after: \(String(describing: retryAfter))")
    case .serverError(let statusCode, let body):
        print("Server error \(statusCode): \(body ?? "")")
    case .networkError(let underlying):
        print("Network: \(underlying)")
    case .unexpectedResponse(let statusCode):
        print("Unexpected HTTP \(statusCode)")
    }
}

Requirements

  • Swift 6.2+
  • macOS 15+ (ARM) / Linux (x86-64, ARM) / Windows 10+ (x86-64, ARM64)

License

See LICENSE for details.

Description

  • Swift Tools 6.2.0
View More Packages from this Author

Dependencies

Last updated: Sun Mar 29 2026 16:05:04 GMT-0900 (Hawaii-Aleutian Daylight Time)