Skip to content
nikcli
Docs
Documentation

Sharing

Public read endpoints for a shared session, in both the page and JSON forms.

Playground

Send these requests to your own running server. Values stay in this browser.

Not connected
How this works

Start a server with nikcli serve --hostname 127.0.0.1 --port 4096. Requests go straight from this page to that address — the browser allows it because loopback counts as a secure origin, and the server allows it because nikcli-ai.dev is in its CORS allowlist.

To try things without touching your real sessions or config, start the server with NIKCLI_TEST_HOME pointed at a throwaway directory — see the guided tour.

Operations

4 endpoints, generated from the server's own OpenAPI document. Every path also accepts the directory and workspace query parameters that select which instance handles the request.

get /s/{shareID} getS:shareID
get /share/{shareID} getShare:shareID
get /api/share/{shareID} getApiShare:shareID
get /api/share/{shareID}/data getApiShare:shareIDData
get /s/{shareID} # getS:shareID
Parameters
Name In Type Required
shareID path string required
directory query string optional
workspace query string optional
Responses
308 308 redirect to /share/:shareID
SDK example
getS:shareID
ts
import { createNikcliClient } from "@nikcli-ai/sdk/httpapi"

const client = createNikcliClient()
await client.getS:shareID({
  ...
})
Try it
get /share/{shareID} # getShare:shareID
Parameters
Name In Type Required
shareID path string required
directory query string optional
workspace query string optional
Responses
200 ShareData application/json
(
  | {
  type: "session"
  data: Session_2
}
  | {
  type: "message"
  data: Message_1
}
  | {
  type: "part"
  data: Part_1
}
  | {
  type: "session_diff"
  data: FileDiff_2[]
}
  | {
  type: "model"
  data: Model[]
})[]
Example response from schema
[
  {
    "type": "session",
    "data": {
      "id": "",
      "slug": "",
      "projectID": "",
      "directory": "",
      "parentID": "",
      "workspaceID": "",
      "summary": {
        "additions": null,
        "deletions": null,
        "files": null,
        "diffs": null
      },
      "share": {
        "url": null
      },
      "github": {
        "owner": null,
        "repo": null,
        "fullName": null,
        "baseBranch": null,
        "headBranch": null,
        "repositoryDirectory": null,
        "cloneUrl": null,
        "htmlUrl": null,
        "private": null,
        "worktree": null,
        "pullRequest": null,
        "lastCommitSha": null,
        "publishedAt": null,
        "publishError": null
      },
      "worktree": {
        "name": null,
        "branch": null,
        "directory": null,
        "repositoryDirectory": null,
        "cleanedAt": null
      },
      "mobile": {
        "platforms": null,
        "primaryPlatform": null,
        "method": null,
        "detectedAt": null,
        "buildStatus": null,
        "lastBuildAt": null,
        "artifacts": null
      },
      "title": "",
      "activeCommand": "",
      "version": "",
      "time": {
        "created": null,
        "updated": null,
        "compacting": null,
        "archived": null
      },
      "permission": [],
      "skills": [],
      "disabledInstructions": [],
      "disabledTools": {},
      "revert": {
        "messageID": null,
        "partID": null,
        "snapshot": null,
        "diff": null
      },
      "lastModel": {
        "providerID": null,
        "modelID": null
      }
    }
  }
]

Generated from the response schema — field values are placeholders, the shape is real.

SDK example
getShare:shareID
ts
import { createNikcliClient } from "@nikcli-ai/sdk/httpapi"

const client = createNikcliClient()
await client.getShare:shareID({
  ...
})
Try it
get /api/share/{shareID} # getApiShare:shareID
Parameters
Name In Type Required
shareID path string required
directory query string optional
workspace query string optional
Responses
200 ShareData application/json
(
  | {
  type: "session"
  data: Session_2
}
  | {
  type: "message"
  data: Message_1
}
  | {
  type: "part"
  data: Part_1
}
  | {
  type: "session_diff"
  data: FileDiff_2[]
}
  | {
  type: "model"
  data: Model[]
})[]
Example response from schema
[
  {
    "type": "session",
    "data": {
      "id": "",
      "slug": "",
      "projectID": "",
      "directory": "",
      "parentID": "",
      "workspaceID": "",
      "summary": {
        "additions": null,
        "deletions": null,
        "files": null,
        "diffs": null
      },
      "share": {
        "url": null
      },
      "github": {
        "owner": null,
        "repo": null,
        "fullName": null,
        "baseBranch": null,
        "headBranch": null,
        "repositoryDirectory": null,
        "cloneUrl": null,
        "htmlUrl": null,
        "private": null,
        "worktree": null,
        "pullRequest": null,
        "lastCommitSha": null,
        "publishedAt": null,
        "publishError": null
      },
      "worktree": {
        "name": null,
        "branch": null,
        "directory": null,
        "repositoryDirectory": null,
        "cleanedAt": null
      },
      "mobile": {
        "platforms": null,
        "primaryPlatform": null,
        "method": null,
        "detectedAt": null,
        "buildStatus": null,
        "lastBuildAt": null,
        "artifacts": null
      },
      "title": "",
      "activeCommand": "",
      "version": "",
      "time": {
        "created": null,
        "updated": null,
        "compacting": null,
        "archived": null
      },
      "permission": [],
      "skills": [],
      "disabledInstructions": [],
      "disabledTools": {},
      "revert": {
        "messageID": null,
        "partID": null,
        "snapshot": null,
        "diff": null
      },
      "lastModel": {
        "providerID": null,
        "modelID": null
      }
    }
  }
]

Generated from the response schema — field values are placeholders, the shape is real.

SDK example
getApiShare:shareID
ts
import { createNikcliClient } from "@nikcli-ai/sdk/httpapi"

const client = createNikcliClient()
await client.getApiShare:shareID({
  ...
})
Try it
get /api/share/{shareID}/data # getApiShare:shareIDData
Parameters
Name In Type Required
shareID path string required
directory query string optional
workspace query string optional
Responses
200 ShareData application/json
(
  | {
  type: "session"
  data: Session_2
}
  | {
  type: "message"
  data: Message_1
}
  | {
  type: "part"
  data: Part_1
}
  | {
  type: "session_diff"
  data: FileDiff_2[]
}
  | {
  type: "model"
  data: Model[]
})[]
Example response from schema
[
  {
    "type": "session",
    "data": {
      "id": "",
      "slug": "",
      "projectID": "",
      "directory": "",
      "parentID": "",
      "workspaceID": "",
      "summary": {
        "additions": null,
        "deletions": null,
        "files": null,
        "diffs": null
      },
      "share": {
        "url": null
      },
      "github": {
        "owner": null,
        "repo": null,
        "fullName": null,
        "baseBranch": null,
        "headBranch": null,
        "repositoryDirectory": null,
        "cloneUrl": null,
        "htmlUrl": null,
        "private": null,
        "worktree": null,
        "pullRequest": null,
        "lastCommitSha": null,
        "publishedAt": null,
        "publishError": null
      },
      "worktree": {
        "name": null,
        "branch": null,
        "directory": null,
        "repositoryDirectory": null,
        "cleanedAt": null
      },
      "mobile": {
        "platforms": null,
        "primaryPlatform": null,
        "method": null,
        "detectedAt": null,
        "buildStatus": null,
        "lastBuildAt": null,
        "artifacts": null
      },
      "title": "",
      "activeCommand": "",
      "version": "",
      "time": {
        "created": null,
        "updated": null,
        "compacting": null,
        "archived": null
      },
      "permission": [],
      "skills": [],
      "disabledInstructions": [],
      "disabledTools": {},
      "revert": {
        "messageID": null,
        "partID": null,
        "snapshot": null,
        "diff": null
      },
      "lastModel": {
        "providerID": null,
        "modelID": null
      }
    }
  }
]

Generated from the response schema — field values are placeholders, the shape is real.

SDK example
getApiShare:shareIDData
ts
import { createNikcliClient } from "@nikcli-ai/sdk/httpapi"

const client = createNikcliClient()
await client.getApiShare:shareIDData({
  ...
})
Try it

Schemas

The 49 schemas reachable from these endpoints. Each is shown one level deep; nested types link to their own entry below. Names ending in _2, _3 and so on are the OpenAPI emitter disambiguating same-named schemas declared by different HttpApi groups — they are distinct shapes, not duplicates.

AgentPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "agent"
  name: string
  source?: {
    value: string
    start: number
    end: number
  }
}
APIError_2
{
  name: "APIError"
  data: {
    message: string
    statusCode?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    isRetryable: boolean
    responseHeaders?: {
      [key: string]: string
    }
    responseBody?: string
    metadata?: {
      [key: string]: string
    }
    classification?: "payload-too-large"
  }
}
AssistantMessage_1
{
  id: string
  sessionID: string
  role: "assistant"
  time: {
    created: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    completed?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
  error?: 
    | ProviderAuthError_1
    | UnknownError_1
    | MessageOutputLengthError_1
    | MessageContextOverflowError_1
    | MessageAbortedError_1
    | StructuredOutputError_1
    | APIError_2
  parentID: string
  modelID: string
  providerID: string
  mode: string
  agent: string
  path: {
    cwd: string
    root: string
  }
  summary?: boolean
  cost: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  tokens: {
    total?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    input: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    output: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    reasoning: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    cache: {
      read: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
      write: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
    }
  }
  structured?: unknown
  finish?: string
}
CompactionPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "compaction"
  auto: boolean
}
FileDiff_2
{
  file: string
  patch: string
  additions: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  deletions: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  status?: 
    | "added" | "deleted" | "modified"
    | null
  before: string
  after: string
}
FilePart_2
{
  id: string
  sessionID: string
  messageID: string
  type: "file"
  mime: string
  filename?: string
  url: string
  source?: FilePartSource_2
}
FilePartSource_2
FileSource_2 | SymbolSource_2 | ResourceSource_2
FilePartSourceText_6
{
  value: string
  start: number
  end: number
}
FileSource_2
{
  text: FilePartSourceText_6
  type: "file"
  path: string
}
JSONSchema_1
{ [key: string]: unknown }
Message_1
UserMessage_1 | AssistantMessage_1
MessageAbortedError_1
{
  name: "MessageAbortedError"
  data: {
    message: string
  }
}
MessageContextOverflowError_1
{
  name: "MessageContextOverflowError"
  data: {
    message: string
    statusCode?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    responseBody?: string
  }
}
MessageOutputLengthError_1
{
  name: "MessageOutputLengthError"
  data: { [key: string]: unknown } | unknown[]
}
Model
{
  id: string
  providerID: string
  api: {
    id: string
    url?: string
    npm: string
  }
  name: string
  family?: string
  capabilities: {
    temperature: boolean
    reasoning: boolean
    attachment: boolean
    toolcall: boolean
    input: {
      text: boolean
      audio: boolean
      image: boolean
      video: boolean
      pdf: boolean
    }
    output: {
      text: boolean
      audio: boolean
      image: boolean
      video: boolean
      pdf: boolean
    }
    interleaved: 
      | boolean
      | {
      field: "reasoning_content" | "reasoning_details"
    }
  }
  cost: {
    input: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    output: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    cache: {
      read: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
      write: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
    }
    experimentalOver200K?: {
      input: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
      output: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
      cache: {
        read: 
          | number
          | "Infinity" | "-Infinity" | "NaN"
        write: 
          | number
          | "Infinity" | "-Infinity" | "NaN"
      }
    }
  }
  limit: {
    context: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    input?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    output: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
  status: 
    | "alpha"
    | "beta"
    | "deprecated"
    | "active"
  options: { [key: string]: unknown }
  headers: {
    [key: string]: string
  }
  release_date: string
  variants?: {
    [key: string]: { [key: string]: unknown }
  }
}
OutputFormat_1
OutputFormatText_1 | OutputFormatJsonSchema_1
OutputFormatJsonSchema_1
{
  type: "json_schema"
  schema: JSONSchema_1
  retryCount: number
}
OutputFormatText_1
{
  type: "text"
}
Part_1
  | TextPart_1
  | SubtaskPart_1
  | ReasoningPart_1
  | FilePart_2
  | ToolPart_1
  | StepStartPart_1
  | StepFinishPart_1
  | SnapshotPart_1
  | PatchPart_1
  | AgentPart_1
  | RetryPart_1
  | CompactionPart_1
PatchPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "patch"
  hash: string
  files: string[]
}
PermissionAction_3
"allow" | "deny" | "ask"
PermissionRule_3
{
  permission: string
  pattern: string
  action: PermissionAction_3
}
PermissionRuleset_3
PermissionRule_3[]
ProviderAuthError_1
{
  name: "ProviderAuthError"
  data: {
    providerID: string
    message: string
  }
}
Range_2
{
  start: {
    line: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    character: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
  end: {
    line: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    character: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
}
ReasoningPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "reasoning"
  text: string
  metadata?: { [key: string]: unknown }
  time: {
    start: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    end?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
}
ResourceSource_2
{
  text: FilePartSourceText_6
  type: "resource"
  clientName: string
  uri: string
}
RetryPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "retry"
  attempt: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  error: APIError_2
  time: {
    created: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
}
Session_2
{
  id: string
  slug: string
  projectID: string
  directory: string
  parentID?: string
  workspaceID?: string
  summary?: {
    additions: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    deletions: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    files: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    diffs?: FileDiff_2[]
  }
  share?: {
    url: string
  }
  github?: SessionGithub_3
  worktree?: SessionWorktree_6
  mobile?: SessionMobile_2
  title: string
  activeCommand?: string
  version: string
  time: {
    created: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    updated: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    compacting?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    archived?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
  permission?: PermissionRuleset_3
  skills?: string[]
  disabledInstructions?: string[]
  disabledTools?: {
    [key: string]: boolean
  }
  revert?: {
    messageID: string
    partID?: string
    snapshot?: string
    diff?: string
  }
  lastModel?: {
    providerID: string
    modelID: string
  }
}
SessionGithub_3
{
  owner: string
  repo: string
  fullName: string
  baseBranch: string
  headBranch: string
  repositoryDirectory?: string
  cloneUrl?: string
  htmlUrl?: string
  private?: boolean
  worktree: SessionWorktree_5
  pullRequest?: {
    number: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    url: string
    title: string
  }
  lastCommitSha?: string
  publishedAt?: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  publishError?: string
}
SessionMobile_2
{
  platforms: (
    | "ios"
    | "android"
    | "expo"
    | "flutter"
    | "react-native")[]
  primaryPlatform: string
  method: string
  detectedAt: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  buildStatus?: 
    | "unknown"
    | "building"
    | "succeeded"
    | "failed"
  lastBuildAt?: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  artifacts?: ({
    platform: string
    path: string
    size?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    createdAt?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  })[]
}
SessionWorktree_5
{
  name: string
  branch: string
  directory: string
  repositoryDirectory?: string
  cleanedAt?: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
}
SessionWorktree_6
{
  name: string
  branch: string
  directory: string
  repositoryDirectory?: string
  cleanedAt?: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
}
ShareData
(
  | {
  type: "session"
  data: Session_2
}
  | {
  type: "message"
  data: Message_1
}
  | {
  type: "part"
  data: Part_1
}
  | {
  type: "session_diff"
  data: FileDiff_2[]
}
  | {
  type: "model"
  data: Model[]
})[]
SnapshotPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "snapshot"
  snapshot: string
}
StepFinishPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "step-finish"
  reason: string
  snapshot?: string
  cost: 
    | number
    | "Infinity" | "-Infinity" | "NaN"
  tokens: {
    total?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    input: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    output: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    reasoning: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    cache: {
      read: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
      write: 
        | number
        | "Infinity" | "-Infinity" | "NaN"
    }
  }
}
StepStartPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "step-start"
  snapshot?: string
}
StructuredOutputError_1
{
  name: "StructuredOutputError"
  data: {
    message: string
    retries: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
}
SubtaskPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "subtask"
  prompt: string
  description: string
  agent: string
  model?: {
    providerID: string
    modelID: string
  }
  command?: string
  background?: boolean
}
SymbolSource_2
{
  text: FilePartSourceText_6
  type: "symbol"
  path: string
  range: Range_2
  name: string
  kind: number
}
TextPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "text"
  text: string
  synthetic?: boolean
  ignored?: boolean
  time?: {
    start: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    end?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
  metadata?: { [key: string]: unknown }
}
ToolPart_1
{
  id: string
  sessionID: string
  messageID: string
  type: "tool"
  callID: string
  tool: string
  state: ToolState_1
  metadata?: { [key: string]: unknown }
}
ToolState_1
  | ToolStatePending_1
  | ToolStateRunning_1
  | ToolStateCompleted_1
  | ToolStateError_1
ToolStateCompleted_1
{
  status: "completed"
  input: { [key: string]: unknown }
  output: string
  title: string
  metadata: { [key: string]: unknown }
  time: {
    start: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    end: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    compacted?: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
  attachments?: FilePart_2[]
}
ToolStateError_1
{
  status: "error"
  input: { [key: string]: unknown }
  error: string
  metadata?: { [key: string]: unknown }
  time: {
    start: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
    end: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
}
ToolStatePending_1
{
  status: "pending"
  input: { [key: string]: unknown }
  raw: string
}
ToolStateRunning_1
{
  status: "running"
  input: { [key: string]: unknown }
  title?: string
  metadata?: { [key: string]: unknown }
  structured?: { [key: string]: unknown }
  content?: (
    | {
    type: "text"
    text: string
  }
    | {
    type: "file"
    data: string
    mime: string
    name?: string
  })[]
  time: {
    start: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
}
UnknownError_1
{
  name: "UnknownError"
  data: {
    message: string
  }
}
UserMessage_1
{
  id: string
  sessionID: string
  role: "user"
  time: {
    created: 
      | number
      | "Infinity" | "-Infinity" | "NaN"
  }
  format?: OutputFormat_1
  summary?: {
    title?: string
    body?: string
    diffs: FileDiff_2[]
  }
  agent: string
  model: {
    providerID: string
    modelID: string
  }
  system?: string
  tools?: {
    [key: string]: boolean
  }
  variant?: string
}