Socket
Book a DemoInstallSign in
Socket

@clavata/sdk

Package Overview
Dependencies
Maintainers
3
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@clavata/sdk

This directory contains the JS version of our SDK.

0.4.0
latest
npmnpm
Version published
Weekly downloads
557
45.81%
Maintainers
3
Weekly downloads
 
Created
Source

Clavata JavaScript SDK

This directory contains the Clavata JavaScript SDK with type definitions.

Getting started

Email support@clavata.ai if you do not already have an API key/token.

Initialize the SDK to get started making requests to the Clavata API.

import Clavata from "@clavata/sdk";

// API key can be provided directly or via environment variable
const clavata = new Clavata({ apiKey: "<YOUR_CLAVATA_API_KEY>" } as Options);

Configuration

The client constructor accepts the following options:

interface Options {
  // Your API key. If not provided you _must_ then set CLAVATA_API_KEY as an environment variable
  apiKey?: string;
  // Optional
  server?: string; // Server endpoint (default: "gateway.app.clavata.ai:443")
  insecure?: boolean; // Use insecure connection. (default: false)
  keepalive?: {
    // Connection keepalive settings
    timeout: number; // How long to wait for a response to a keepalive ping before considering the connection dead (in ms). (default: 10000)
    permitWithoutCalls: boolean; // Allows keepalive pings to maintain idle connections. (default: true)
    time: number; // How frequently to send keepalive pings to check if the connection is alive (in ms). (default: 10000)
  };
  maxMessageLength?: number; // Max message size (default: 100MB)
  retryConfig:
    | {
        // Configuration for automatic retries. Will retry by default. Set to `false` to disable this. See https://grpc.io/docs/guides/retry for more info.
        maxAttempts?: number; // Maximum number of retry attempts (default: 5)
        initialBackoff?: string; // Initial backoff time in milliseconds (default: "1s")
        maxBackoff?: string; // Maximum backoff time (default: "30s")
        backoffMultiplier?: number; // Multiplier for backoff time after each retry (default: 2.0)
        jitter?: number; // Jitter factor between 0 and 1 (default: 0.2, 0 = no jitter, 1 = full jitter)
      }
    | false;
}

If neither an API key is provided to the constructor nor is a process.env.CLAVATA_API_KEY environment variable set then the constructor will throw an error.

RPC Methods

getJob(jobId: string): Promise<Job | undefined>

  • Retrieves a job by its UUID.

listJobs(request: ListJobsRequest): Promise<ListJobsResponse>

  • Lists jobs with filtering parameters.

createJob(request: CreateJobRequest): Promise<CreateJobResponse[]>

  • Creates a new job with the provided content data and returns the id and status of the job that can be requested at a later point in time. If you need to await the result use evaluate instead.

evaluate(request: EvaluateRequest): Promise<AsyncIterable<EvaluateMessage | StreamError>>

  • Evaluates each input and returns a stream of responses or errors. Order is not guaranteed, so using metadata or a contentHash is advised when sending multiple pieces to evaluate in a single call.
  • Example:
const stream = clavata.evaluate({
  contentData: [
    {
      metadata: { id: "1" },
      content: { value: "Hello, world!", $case: "text" },
      contentType: "text",
    },
    {
      metadata: { id: "2" },
      content: { value: Buffer.from("<BASE64_DATA>", "base64"), $case: "image" },
      contentType: "image/png",
    },
    {
      metadata: { id: "3" },
      content: { value: "<IMAGE_URL>", $case: "imageUrl" },
      contentType: "image/jpeg",
    },
  ],
  policyId: "00000000-0000-0000-0000-000000000000",
});

for await (const item of stream) {
  if (item instanceof StreamError) throw item;

  const { metadata, report } = item;
  console.log({ id: metadata?.id, matches: report?.matches });
}

Refusals

Under certain circumstances, the Clavata API will refuse to evaluate content as requested. There are only a few possible reasons for this:

  • The content (image) matches a known hash in our CSAM database. This can be either an exact match or a perceptual hash match.
  • The content (image) is in an unsupported format. Currently, Clavata supports webp, png and jpg images.
  • The content was corrupt. Usually because the content was incomplete or the encoding (for images) was incorrect.

When a refusal occurs, a StreamError will be returned (for evaluate) or thrown (for createJob). You can check whether the error was caused by a refusal using the getRefusalReason() method on the StreamError type. If the error was not caused by a refusal, this method will return undefined. If the error is due to a refusal, a RefusalReason will be returned.

The RefusalReason type is a enum with strings matching one of:

  • "CSAM"
  • "UNSUPPORTED_IMAGE_FORMAT"
  • "INVALID_IMAGE"

There is also an "UNKNOWN" option, but this case indicates something went wrong decoding the "reason" information in the response.


import { RefusalReason } from "@clavata/sdk";

const stream = clavata.evaluate(...)

for await (const item of stream) {
  if (item instanceof StreamError) {
    const reason = item.getRefusalReason();
    if (!reason) {
      // Not a refusal, you can check the other possible identification methods like
      if (item.isTransient()) {
        // Transient error so we can retry
      }
    }

    // It was a refusal, so we can use a switch statement to figure out why
    switch (reason) {
      case RefusalReason.CSAM:
        // Handle CSAM appropriately
        break;
      case RefusalReason.UNSUPPORTED_IMAGE_FORMAT:
        // Convert image and try again
        break;
      case RefusalReason.INVALID_IMAGE:
        // data corruption, maybe try to re-download from CDN and try again?
        break;
      default:
        // unknown reason for refusal
    }
  }
}

Getting the Refusal Error

If you prefer, you can convert a StreamError into a RefusalError with the toRefusalError() method. Once again, if the error was not caused by a refusal, this method will return undefined. If, however, a refusal did occur the RefusalError type that is returned has the following interface that you can use to understand why:

interface RefusalError {
  isCSAM(): boolean;
  isUnsupportedImageFormat(): boolean;
  isInvalidImage(): boolean;
  isUnknown(): boolean;
  getReason(): RefusalReason;
}

// So you can do this:
if (item instanceof StreamError) {
  const refusalErr = item.toRefusalError();
  if (refusalErr.isCSAM()) {
    // Take action based on the content having been CSAM
  }
}

Which interface you use to determine the reason is up to you, they are functionally equivalent.

Refusals and createJob

When calling createJob, a promise is returned. If an error occurs, that error is automatically converted to a StreamError by the SDK and re-thrown. You can then catch the StreamError and check for refusals the same way.

Contributing

Update the version with npm version to the next SEMVER then run npm publish.

FAQs

Package last updated on 07 Aug 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.