Low-level SDK
Use the supported API v2 SDK directly from server-side TypeScript.
@edgestore/sdk is the public, low-level client for EdgeStore API v2. Use it
when you need API operations that are not tied to an EdgeStore router. For
router-derived bucket names, input, path, and metadata types, use the
backend client instead.
The SDK is server-only. Project secrets and management tokens must never be included in browser bundles.
Project client
Project credentials expose runtime operations for the credential's current project. The reserved project selector is handled internally.
import { createEdgeStoreSdk } from '@edgestore/sdk';
const sdk = createEdgeStoreSdk({
credentials: {
accessKey: process.env.EDGE_STORE_ACCESS_KEY!,
secretKey: process.env.EDGE_STORE_SECRET_KEY!,
},
});
const file = await sdk.runtime.uploads.upload({
bucket: 'documents',
source: pdfBlob,
fileName: 'invoice.pdf',
metadata: { invoiceId: invoice.id },
signal,
onProgress: ({ percentage, phase }) => {
console.log(phase, percentage);
},
});The upload helper selects single or multipart upload automatically, reports
progress, supports cancellation, and waits for upload processing to finish.
Upload creation is never retried because it is not idempotent. Signed storage
transfers may be retried safely, and processing polls follow Retry-After. You
can also use runtime.uploads.request, createParts, and completeMultipart
when you need to manage transfer details yourself.
Sources can be text, a Blob, an ArrayBuffer or typed-array view, or a
known-size Web ReadableStream:
await sdk.runtime.uploads.upload({
bucket: 'archives',
source: { stream, sizeBytes },
fileName: 'archive.tar',
});
await sdk.runtime.uploads.uploadFromUrl({
bucket: 'imports',
url: 'https://example.com/report.csv',
});The defaults are a 100 MiB multipart threshold, 16 MiB parts, concurrency 4, a
30-second control timeout, no transfer timeout, and a 60-second processing
timeout. Configure upload defaults with the upload option on
createEdgeStoreSdk; pass an AbortSignal for per-operation cancellation or
deadlines.
Runtime resources
const page = await sdk.runtime.files.search({
bucket: 'documents',
filter: { metadata: { ownerId: user.id } },
pagination: { limit: 50 },
});
if (page.pagination.hasMore) {
const nextPage = await sdk.runtime.files.search({
bucket: 'documents',
pagination: {
cursor: page.pagination.nextCursor ?? undefined,
limit: 50,
},
});
}
const { signedUrls } = await sdk.runtime.files.generateSignedReadUrls({
bucket: 'documents',
urls: page.files.map((file) => file.url),
expiresIn: 15 * 60,
});
await sdk.runtime.files.confirm({ file: { id: file.file.id } });
await sdk.runtime.files.delete({ file: { key: file.file.key } });
const batch = await sdk.runtime.files.deleteMany({
files: [{ id: file.file.id }, { url: legacyFileUrl }],
});
for (const result of batch.results) {
if (!result.success) console.error(result.fileRef, result.error.code);
}Runtime resources also include projects, buckets, file lookup, signed read
URLs, access tokens, upload inspection, cancellation, and singular or plural
restore operations. Singular mutations throw EdgeStoreFileMutationError for
an item failure; plural mutations return the complete partial result.
Management client
A management token uses Bearer authentication and exposes account, project, credential, token, and membership resources. Runtime calls can select a project per operation or create an eagerly scoped runtime client once.
const management = createEdgeStoreSdk({
credentials: {
token: process.env.EDGE_STORE_MANAGEMENT_TOKEN!,
},
});
const projects = await management.management.projects.list({
account: 'account-id',
});
const project = management.runtime.forProject(projects.projects[0]!.id);
const buckets = await project.buckets.list();
// An explicit selector remains useful for one-off calls.
const anotherProject = await management.runtime.projects.get({
project: 'another-project-id',
});
const { accessUrls } =
await management.management.files.generateAccessUrls({
project: projects.projects[0]!.id,
files: [{ id: 'file-id' }],
expiresIn: 15 * 60,
});Reusing SDK types
Common runtime workflows have named public input and result types:
import type {
RuntimeFileLookupInput,
RuntimeFileLookupResult,
RuntimeSignedReadUrlsGenerateInput,
RuntimeSignedReadUrlsGenerateResult,
RuntimeUploadInput,
RuntimeUploadResult,
} from '@edgestore/sdk';For any other operation, derive its friendly input and resolved output from the
public SDK interface. This includes SDK selectors such as account, project,
and bucket, plus signal.
import type { ManagementEdgeStoreSdk } from '@edgestore/sdk';
type CreateProjectMethod =
ManagementEdgeStoreSdk['management']['projects']['create'];
type CreateProjectInput = Parameters<CreateProjectMethod>[0];
type CreateProjectOutput = Awaited<ReturnType<CreateProjectMethod>>;You can use the same pattern with a configured SDK value:
type LookupInput = Parameters<typeof sdk.runtime.files.lookup>[0];
type LookupOutput = Awaited<
ReturnType<typeof sdk.runtime.files.lookup>
>;The generated OpenAPI operation types remain internal. Deriving from the public interface keeps application types aligned with the supported SDK surface.
Errors
import { EdgeStoreApiError, EdgeStoreNetworkError } from '@edgestore/sdk';
try {
await sdk.runtime.files.lookup({ file: { url } });
} catch (error) {
if (error instanceof EdgeStoreApiError) {
console.error(error.status, error.code, error.requestId);
} else if (error instanceof EdgeStoreNetworkError) {
console.error('The API could not be reached', error.cause);
}
}API errors preserve the HTTP status, machine-readable code, details, request ID, and retry guidance. Abort, network, upload, cancellation, and processing timeout errors have dedicated classes.
Custom environments
Use apiUrl for a compatible API v2 deployment and fetch to provide a
custom server-side transport implementation.
const sdk = createEdgeStoreSdk({
credentials: { accessKey, secretKey },
apiUrl: 'https://api.example.com/v2',
fetch: instrumentedFetch,
});apiUrl is the complete v2 URL. The SDK does not append /v2 to an explicit
value.