Back to Core SDK

Rawback developer documentation

Core SDK integration guide

Build an approved Node.js photo agent or integration with browser-based device authentication, durable sessions, and typed Rawback services.

Access and requirements

@rawback/sdk is the headless Node.js application kernel used by Rawback clients and approved photo agents. It provides authentication, credential refresh, configuration, typed GraphQL operations, and domain services without importing a user-interface framework.

The package is publicly downloadable, but it is UNLICENSED and is not licensed for third-party use, modification, redistribution, or production deployment without written Rawback approval. Contact [email protected] before building or shipping an integration.

Your runtime must provide:

  • Node.js 26 or newer, or a compatible Bun runtime.
  • ECMAScript modules (import). CommonJS is not published.
  • A server, desktop main process, worker, or CLI environment. Do not bundle the SDK into browser code.
  • A stable name and version for your integration's client identity.

This guide covers client authentication and Rawback API access. Direct SFTP transfer orchestration, UploadManager, and upload-state migration are intentionally outside its scope.

Install

After Rawback approves the integration, add the package to your Node.js project:

Shell
pnpm add @rawback/sdk

The package has a single ESM entry point and publishes its generated GraphQL types and documents alongside the higher-level client APIs. Review the current package version and metadata on the npm package page before upgrading.

Create a client

Every request identifies the consuming application. Use a stable source name, your deployed application version, and an equally stable user agent:

TypeScript
import { createRawbackSdk } from '@rawback/sdk'

const rawback = await createRawbackSdk({
  identity: {
    source: 'studio-workflow',
    version: '1.0.0',
    userAgent: 'studio-workflow/1.0.0',
  },
})

By default, the SDK reads ~/.rawback/config.yml and ~/.rawback/credentials.json. This lets an approved desktop or CLI integration share the active Rawback account. Existing credentials are attached to requests, refreshed after an authentication failure, and atomically replaced when Rawback returns a new token pair.

Use explicit paths when the integration owns a separate session or configuration boundary:

TypeScript
import { join } from 'node:path'
import { createRawbackSdk } from '@rawback/sdk'

const stateDirectory = '/var/lib/studio-workflow/rawback'

const rawback = await createRawbackSdk({
  configPath: join(stateDirectory, 'config.yml'),
  credentialsPath: join(stateDirectory, 'credentials.json'),
  identity: {
    source: 'studio-workflow',
    version: '1.0.0',
    userAgent: 'studio-workflow/1.0.0',
  },
})

Constructor options override values read from the config file. Approved development environments can set apiHost; production integrations should use Rawback's default API host unless Rawback provides another endpoint. A custom fetch implementation can add platform networking behavior, but it must preserve request headers and cancellation.

Authentication

Restore an existing session

The simplest startup path is to construct the SDK with its normal credential path and make an authenticated service call. When an access token is rejected, the client coalesces concurrent refresh attempts, persists the new token pair, and retries the request once.

TypeScript
const account = await rawback.services.account.status()

if (account.error) throw account.error
if (!account.data?.me) throw new Error('Sign in to Rawback first')

Browser-approved device sign-in

For a new interactive integration, use device authentication instead of collecting the user's Rawback password. Create an unauthenticated SDK instance, open the approval URL in the user's browser, and poll no faster than the interval returned by Rawback:

TypeScript
import { createRawbackSdk, type RawbackSdkOptions } from '@rawback/sdk'

const options: RawbackSdkOptions = {
  credentialsPath: '/var/lib/studio-workflow/rawback/credentials.json',
  identity: {
    source: 'studio-workflow',
    version: '1.0.0',
    userAgent: 'studio-workflow/1.0.0',
  },
}

const loginSdk = await createRawbackSdk({
  ...options,
  credentials: null,
})
const device = await loginSdk.auth.createDeviceSession()
const approvalUrl = `https://rawback.app/auth/device/${encodeURIComponent(device.sessionId)}`

console.log(`Approve this sign-in: ${approvalUrl}`)

const wait = (milliseconds: number) =>
  new Promise((resolve) => setTimeout(resolve, milliseconds))

let approved = false
while (Date.now() < Date.parse(device.expiresAt)) {
  await wait(Math.max(2, device.pollIntervalSeconds) * 1_000)

  const result = await loginSdk.auth.pollDeviceSession(
    device.sessionId,
    device.pollToken,
  )

  if (result.status === 'denied') throw new Error('Rawback access was denied')
  if (result.status === 'approved') {
    approved = true
    break
  }
}

if (!approved) throw new Error('Rawback device sign-in expired')

// Device approval persisted credentials. Build a fresh authenticated client.
const rawback = await createRawbackSdk(options)

pollToken, access tokens, and refresh tokens are secrets. Never print or send them to analytics. Respect expiresAt, support cancellation with an AbortSignal, and stop polling after approval, denial, expiry, or user cancellation.

The composed SDK's API client captures credentials when it is created. After device login or rawback.auth.logout(), discard that SDK instance and create a new one before making more service calls. This prevents an in-memory client from drifting from the credential file.

Typed domain services

The services object is the preferred integration surface. Each operation accepts generated variables and returns a { data, error } result. Always inspect error before using partial data.

TypeScript
const result = await rawback.services.photos.library({
  pagination: { page: 1, pageSize: 40 },
})

if (result.error) throw result.error

for (const photo of result.data?.images?.edges ?? []) {
  console.log(photo.id, photo.filename, photo.capturedAt)
}

Available service groups include:

| Service | Operations | | --------------------- | ------------------------------------------------------------ | | account | Authentication status and dashboard data | | photos | Filtered photo lists and desktop-style library pages | | albums | List, read, create, update, delete, and image/tag membership | | articles | List, edit, publish, unpublish, and delete album stories | | dreams | List, inspect, and retry generated daily recaps | | shares | Read incoming/outgoing shares and update or delete shares | | uploadSessions | Read upload activity and outcomes | | usage and pricing | Read account limits, consumption, and plan data |

SFTP credential and upload-preflight services also exist for approved upload clients, but obtaining a credential is not a complete or safe upload integration by itself. Coordinate with Rawback before using those operations.

Keep pagination explicit and bounded. Treat returned URLs as short-lived application data rather than permanent identifiers, and use numeric Rawback IDs for follow-up operations.

Lower-level clients

Use the generated documents with rawback.client.graphql when a higher-level service does not expose the cancellation or composition boundary you need:

TypeScript
import { PhotosDocument } from '@rawback/sdk'

const controller = new AbortController()
const result = await rawback.client.graphql.query({
  query: PhotosDocument,
  variables: {
    filter: { search: 'Iceland' },
    pagination: { page: 1, pageSize: 20 },
  },
  signal: controller.signal,
})

if (result.error) throw result.error

The typed document fixes the result and variable types at compile time. Do not construct GraphQL query strings manually or depend on fields outside the published document contracts.

rawback.client.http.request() and requestJson() are available for Rawback REST endpoints that have been approved for your integration. They resolve relative paths against the configured API host, attach client identity, attach the active bearer token for authenticated requests, and preserve the supplied AbortSignal. Never use them to call arbitrary third-party URLs.

Errors and cancellation

Service and compatibility GraphQL calls return a RawbackGraphqlError in the result when Rawback responds with GraphQL errors. The error can include partial data, so your application must decide explicitly whether that partial response is usable.

Transport, invalid JSON, configuration, credential-file, and transient refresh failures are thrown. Handle the exported error classes when the distinction changes your user experience:

TypeScript
import {
  ConfigError,
  CredentialsError,
  JsonResponseError,
  RawbackGraphqlError,
  RawbackHttpError,
} from '@rawback/sdk'

try {
  const result = await rawback.services.account.dashboard()
  if (result.error) throw result.error
  return result.data
} catch (error) {
  if (error instanceof RawbackHttpError && error.status === 429) {
    throw new Error('Rawback rate limit reached; retry later', { cause: error })
  }
  if (error instanceof ConfigError || error instanceof CredentialsError) {
    throw new Error(`Rawback local state is unavailable: ${error.path}`, {
      cause: error,
    })
  }
  if (
    error instanceof RawbackGraphqlError ||
    error instanceof JsonResponseError
  ) {
    throw new Error('Rawback returned an unusable response', { cause: error })
  }
  throw error
}

Use AbortSignal on device-auth, raw GraphQL, and HTTP operations when work is tied to a request, window, job, or shutdown lifecycle. Cancellation is not a failure worth retrying automatically. Retry only idempotent operations, use bounded exponential backoff for transient failures, and honor server rate-limit guidance.

Production security

  • Keep @rawback/sdk in a trusted Node.js process. Never expose refresh tokens, the device poll token, or credential files to browser JavaScript.
  • Give each deployment or user boundary its own credential path. Do not use one global credential file to impersonate multiple Rawback accounts.
  • On Linux and macOS, the SDK creates secret-bearing files with restrictive permissions. Preserve those permissions when copying, backing up, or restoring state.
  • Do not log credentials, complete API bodies, private photo metadata, or signed media URLs. Redact them from error reporting and telemetry.
  • Set a truthful client source and version. Update the version for every deployed release so Rawback can diagnose compatibility problems.
  • Pin and review SDK upgrades, compile against the new generated types, and test authentication refresh and core service calls before deployment.
  • Dispose of an SDK instance after login or logout and after changing its configuration or credential path.
  • Obtain written Rawback approval before third-party use or production deployment. Package availability on npm does not grant a license.

The SDK source repository is private. Use the published TypeScript declarations and this integration contract as the supported surface, and contact [email protected] when a required operation is missing.