@omniq/sdk
v0.1.0
Published
OMNIQ Platform SDK — typed API client for project management
Maintainers
Readme
@omniq/sdk
Typed SDK for the OMNIQ Platform API. Zero dependencies — uses native fetch.
Quick Start
npm install @omniq/sdk
# or
pnpm add @omniq/sdkimport { OmniqClient } from '@omniq/sdk';
const client = new OmniqClient({
baseUrl: 'https://app.omniq.pro/api/v1',
token: 'pat_abc123…',
});
const projects = await client.projects.list();
console.log(projects);Authentication
Personal Access Token (recommended)
Create a PAT in Settings → Tokens and pass it to the client. Best for scripts, CI pipelines, and MCP servers.
const client = new OmniqClient({
baseUrl: 'https://app.omniq.pro/api/v1',
token: process.env.OMNIQ_TOKEN,
});Cookie (server-side proxy)
When proxying through a backend that already holds a session cookie,
forward the Cookie header instead:
const client = new OmniqClient({
baseUrl: 'https://app.omniq.pro/api/v1',
cookieHeader: req.headers.cookie,
});Email / Password
Authenticate programmatically and receive a session. The login response
sets an httpOnly cookie — use cookieHeader for subsequent calls.
const client = new OmniqClient({
baseUrl: 'https://app.omniq.pro/api/v1',
});
const { user } = await client.auth.login({
email: '[email protected]',
password: 'secret',
});Configuration
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| baseUrl | string | — | API root URL (required) |
| token | string | — | Personal Access Token for Bearer auth |
| cookieHeader | string | — | Raw Cookie header value for server-side proxy |
| maxRetries | number | 3 | Retry count for 5xx / network errors |
Resources
Auth — client.auth
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| login(data) | POST | /auth/login | LoginResponse |
| refresh() | POST | /auth/refresh | { success: boolean } |
| logout() | POST | /auth/logout | void |
| logoutAll() | POST | /auth/logout-all | void |
| me() | GET | /auth/me | { user: User } |
Projects — client.projects
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| list() | GET | /projects | Project[] |
| get(id) | GET | /projects/:id | Project |
| create(data) | POST | /projects | Project |
| update(id, data) | PATCH | /projects/:id | Project |
| delete(id) | DELETE | /projects/:id | void |
| listMembers(projectId) | GET | /projects/:id/members | ProjectMember[] |
| addMember(projectId, data) | POST | /projects/:id/members | void |
| removeMember(projectId, userId) | DELETE | /projects/:id/members/:userId | void |
const project = await client.projects.create({
name: 'Payments',
key: 'PAY',
description: 'Payment processing service',
});Issues — client.issues
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| list(params?) | GET | /issues | PaginatedResponse<Issue> |
| listAll(params?) | GET | /issues (auto-paginated) | AsyncGenerator<Issue> |
| get(id) | GET | /issues/:id | Issue |
| create(data) | POST | /issues | Issue |
| update(id, data) | PATCH | /issues/:id | Issue |
| delete(id) | DELETE | /issues/:id | void |
| updateStatus(id, status) | POST | /issues/:id/status | Issue |
| bulkUpdate(data) | POST | /issues/bulk | Issue[] |
| addComment(issueId, data) | POST | /issues/:id/comments | Comment |
| addLink(issueId, data) | POST | /issues/:id/links | IssueLink |
const issue = await client.issues.create({
projectId: 'proj_1',
title: 'Fix login bug',
priority: 'high',
type: 'bug',
});
await client.issues.updateStatus(issue.id, 'in_progress');Sprints — client.sprints
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| list({ projectId }) | GET | /sprints | Sprint[] |
| get(id) | GET | /sprints/:id | Sprint |
| create(data) | POST | /sprints | Sprint |
| update(id, data) | PATCH | /sprints/:id | Sprint |
| delete(id) | DELETE | /sprints/:id | void |
| start(id) | POST | /sprints/:id/start | Sprint |
| close(id, transferToSprintId?) | POST | /sprints/:id/close | Sprint |
| burndown(id) | GET | /sprints/:id/burndown | BurndownPoint[] |
| velocity({ projectId }) | GET | /sprints/velocity | VelocityData |
const sprints = await client.sprints.list({ projectId: 'proj_1' });
const burndown = await client.sprints.burndown(sprints[0].id);
const velocity = await client.sprints.velocity({ projectId: 'proj_1' });
// Close sprint and transfer undone issues
await client.sprints.close(sprint.id, nextSprint.id);Wiki — client.wiki
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| listSpaces({ projectId }) | GET | /wiki/spaces | WikiSpace[] |
| createSpace(data) | POST | /wiki/spaces | WikiSpace |
| listPages({ spaceId }) | GET | /wiki/pages | WikiPage[] |
| createPage(data) | POST | /wiki/pages | WikiPage |
| updatePage(id, data) | PATCH | /wiki/pages/:id | WikiPage |
| pageVersions(id) | GET | /wiki/pages/:id/versions | WikiPageVersion[] |
| restorePage(pageId, versionId) | POST | /wiki/pages/:id/restore/:versionId | WikiPage |
| search({ projectId, q }) | GET | /wiki/search | WikiSearchResult[] |
| templates() | GET | /wiki/templates | WikiTemplate[] |
const results = await client.wiki.search({
projectId: 'proj_1',
q: 'onboarding',
});Calendar — client.calendar
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| listEvents({ start, end, projectId?, userId? }) | GET | /calendar/events | CalendarEvent[] |
| createEvent(data) | POST | /calendar/events | CalendarEvent |
| updateEvent(id, data) | PATCH | /calendar/events/:id | CalendarEvent |
| deleteEvent(id) | DELETE | /calendar/events/:id | void |
| listResources({ start, end, projectId? }) | GET | /calendar/resources | CalendarResourceEntity[] |
| exportIcs({ start, end }) | GET | /calendar/export.ics | Response (raw) |
const events = await client.calendar.listEvents({
start: '2025-06-01',
end: '2025-06-30',
projectId: 'proj_1',
});
const icsResponse = await client.calendar.exportIcs({
start: '2025-06-01',
end: '2025-06-30',
});
const ics = await icsResponse.text();AI — client.ai
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| chat(data) | POST | /ai/chat | AiChatResponse |
| chatStream(data) | POST | /ai/chat/stream | Response (raw SSE stream) |
| generate(data) | POST | /ai/generate | { content, tokensUsed } |
| estimate(data) | POST | /ai/estimate | AiEstimateResponse |
| plan(data) | POST | /ai/plan | { content, tokensUsed } |
| summarize(data) | POST | /ai/summarize | { content, tokensUsed } |
| insights({ projectId }) | GET | /ai/insights | { content, tokensUsed } |
const estimate = await client.ai.estimate({
title: 'Add OAuth2 login',
description: 'Support Google and GitHub OAuth2 flows',
});
console.log(`${estimate.storyPoints} SP (${estimate.confidence}% confidence)`);
const reply = await client.ai.chat({
message: 'Summarize the current sprint progress',
projectId: 'proj_1',
});
console.log(reply.content);Notifications — client.notifications
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| list({ unreadOnly? }?) | GET | /notifications | { data: Notification[], unreadCount } |
| markRead(id) | POST | /notifications/:id/read | void |
| markAllRead() | POST | /notifications/read-all | void |
const { data: notifications, unreadCount } = await client.notifications.list({
unreadOnly: true,
});
for (const n of notifications) {
await client.notifications.markRead(n.id);
}Tokens — client.tokens
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| list() | GET | /tokens | PersonalAccessToken[] |
| create(data) | POST | /tokens | CreatedToken |
| delete(id) | DELETE | /tokens/:id | void |
const { token } = await client.tokens.create({
name: 'CI pipeline',
scopes: ['issues:read', 'issues:write'],
expiresAt: '2026-12-31T23:59:59Z',
});
// Store `token` securely — it is only shown once.GitLab — client.gitlab
| Method | HTTP | Path | Returns |
| --- | --- | --- | --- |
| listActivity(projectId) | GET | /git/events | GitLabEvent[] |
| linkCommit(issueId, sha, url?) | POST | /git/commits/link | void |
const events = await client.gitlab.listActivity('proj_1');
await client.gitlab.linkCommit('issue_1', 'abc123def', 'https://gitlab.com/…/commit/abc123def');Pagination
Methods returning PaginatedResponse<T> include data, total, page, and limit fields.
For convenience, listAll() methods return an AsyncGenerator that handles page fetching automatically:
for await (const issue of client.issues.listAll({ projectId: 'proj_1' })) {
console.log(issue.key, issue.title);
}
// With filters
for await (const issue of client.issues.listAll({
projectId: 'proj_1',
status: 'in_progress',
assigneeId: 'user_1',
})) {
process.stdout.write(`${issue.key} `);
}The paginator fetches 50 items per page and stops when all items are consumed.
Error Handling
All API errors throw OmniqApiError with status, statusText, and body properties:
import { OmniqClient, OmniqApiError } from '@omniq/sdk';
try {
await client.projects.get('nonexistent');
} catch (error) {
if (error instanceof OmniqApiError) {
console.error(error.status); // 404
console.error(error.statusText); // "Not Found"
console.error(error.body); // parsed JSON error body
}
}Automatic retries — Server errors (5xx) and network failures are retried up to maxRetries times
(default 3) with exponential backoff (1 s → 2 s → 4 s, capped at 10 s). Client errors (4xx) are
never retried and throw immediately.
TypeScript
The SDK is fully typed. All entity types, input types, enums, and utility types are exported from the package root:
import { OmniqClient } from '@omniq/sdk';
import type {
Issue,
CreateIssueInput,
IssueStatus,
IssuePriority,
StoryPoints,
PaginatedResponse,
} from '@omniq/sdk';
async function moveToReview(client: OmniqClient, issueId: string): Promise<Issue> {
return client.issues.updateStatus(issueId, 'review');
}Enums / Unions — Role, IssueStatus, IssuePriority, IssueType, StoryPoints, SprintStatus, CalendarEventType, CalendarEventStatus, ContentFormat, CommentSource, NotificationType, EntityType
Entities — User, Project, Issue, Sprint, Comment, IssueLink, WikiSpace, WikiPage, WikiPageVersion, WikiTemplate, CalendarEvent, CalendarResourceEntity, Notification, PersonalAccessToken, CreatedToken, ProjectMember, GitLabEvent, GitLabCommitLink
Inputs — LoginInput, CreateProjectInput, AddMemberInput, CreateIssueInput, UpdateIssueInput, BulkUpdateIssueInput, CreateCommentInput, CreateIssueLinkInput, IssueListParams, CreateSprintInput, UpdateSprintInput, CreateWikiSpaceInput, CreateWikiPageInput, UpdateWikiPageInput, CreateCalendarEventInput, UpdateCalendarEventInput, CreateTokenInput, AiChatInput, AiGenerateInput, AiEstimateInput
Responses — LoginResponse, AuthTokens, AiChatResponse, AiEstimateResponse, PaginatedResponse<T>, BurndownPoint, VelocityEntry, VelocityData, WikiSearchResult
Resource classes — AuthResource, ProjectsResource, IssuesResource, SprintsResource, WikiResource, CalendarResource, AIResource, NotificationsResource, TokensResource, GitLabResource
License
MIT
