MemoryKit

Error Handling

HTTP status codes, error response format, typed SDK exceptions, and retry strategies.

All API errors return a consistent JSON structure. The SDKs throw typed exceptions so you can handle each case explicitly.

Error response format

{
  "error": {
    "type": "validation_error",
    "message": "content: field required",
    "request_id": "req_abc123"
  }
}

Every error includes a request_id for debugging. Include it when contacting support.

HTTP status codes

CodeTypeDescriptionRetryable?
400bad_requestMalformed requestNo
401authentication_errorMissing or invalid API keyNo
403forbiddenInsufficient permissionsNo
404not_foundResource does not existNo
409conflictDuplicate resourceNo
422validation_errorRequest body failed validationNo
429rate_limit_errorRate limit or quota exceededYes
500server_errorInternal server errorYes
502bad_gatewayUpstream service errorYes
503service_unavailableService temporarily downYes

SDK error handling

The SDKs throw typed exceptions that you can catch individually — no string matching needed.

import {
  MemoryKitError,
  AuthenticationError,
  RateLimitError,
  NotFoundError,
  ValidationError,
} from "memorykit";
 
try {
  const result = await mk.memories.search({ query: "..." });
} catch (error) {
  if (error instanceof AuthenticationError) {
    // 401 — check your API key
  } else if (error instanceof RateLimitError) {
    // 429 — back off and retry
    console.log(`Retry after ${error.retryAfter}s`);
  } else if (error instanceof ValidationError) {
    // 400/422 — fix the request
    console.log(error.errors);
  } else if (error instanceof NotFoundError) {
    // 404 — resource doesn't exist
  } else if (error instanceof MemoryKitError) {
    // Other API errors
    console.log(error.statusCode, error.message);
  }
}

The SDKs automatically retry 429 and 5xx errors with exponential backoff (up to maxRetries times). You don't need to implement retry logic for these cases.

Rate limits

When you exceed per-endpoint rate limits, the API returns 429 with Retry-After and X-RateLimit-* headers. The SDKs automatically retry these with exponential backoff.

See Limits & Quotas for the full rate limit table by endpoint.

Custom retry logic

If you need custom retry behavior beyond what the SDKs provide:

async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error instanceof RateLimitError && i < maxRetries - 1) {
        const delay = Math.min(1000 * 2 ** i + Math.random() * 1000, 30000);
        await new Promise((r) => setTimeout(r, delay));
      } else {
        throw error;
      }
    }
  }
  throw new Error("Max retries exceeded");
}
 
// Usage
const result = await withRetry(() => mk.memories.search({ query: "..." }));

Quota errors

If you exceed your plan's monthly limits, query and ingest endpoints return 429 with a message indicating which quota was exceeded.

{
  "error": {
    "type": "rate_limit_error",
    "message": "Monthly query quota exceeded. Upgrade your plan or wait until the next billing cycle.",
    "request_id": "req_abc123"
  }
}

Check your current usage with the status endpoint:

const status = await mk.status();
console.log(`Queries: ${status.usage.queries_this_month}/${status.usage.queries_limit}`);
console.log(`Documents: ${status.usage.memories_total}/${status.usage.memories_limit}`);

See Limits & Quotas for plan details.

Edit on GitHub

On this page