Resources
Every resource family on the Gigadrive Network client, with its methods and the endpoint behind each one.
Each area of Gigadrive Network hangs off the client as a resource object, and every method maps to one HTTP endpoint. The names repeat across families, so list, get, create and delete mean the same thing wherever you meet them.
| Property | Covers | Feature docs |
|---|---|---|
client.organizations | organizations, members, product access, organization variables | Organizations |
client.applications | applications, hostnames, application variables, request logs | Getting started |
client.storage | buckets, objects, upload sessions, trash | File storage |
client.deployments | deployments, artifact upload, build logs | Deployments |
client.aiGateway | chat completions, responses, models, speech, transcription, video | AI Gateway |
client.apiKeys | application-scoped API keys | API keys |
client.stickySessions | signed URLs that pin related requests to one Function | Sticky sessions |
client.imageOptimization | managed image URLs and cache purge | Image optimization |
client.storage and client.applications.storage are the same object. Prefer client.storage.
Every example uses a client built as described in Authentication:
import { GigadriveClient } from '@gigadrive/sdk';
const client = new GigadriveClient();
const applicationId = process.env.GIGADRIVE_APPLICATION_ID as string;Organizations
| Method | Signature | Endpoint |
|---|---|---|
organizations.list | (query?: ListQuery) => Promise<Paginated<Organization>> | GET /organizations |
organizations.get | (organizationId: string) => Promise<Organization> | GET /organizations/{id} |
organizations.create | (input: CreateOrganizationInput) => Promise<Organization> | POST /organizations |
organizations.members.list | (organizationId, query?: ListQuery) => Promise<Paginated<OrganizationMember>> | GET /organizations/{id}/members |
organizations.products.list | (organizationId, query?: ListQuery) => Promise<Paginated<OrganizationProductAccess>> | GET /organizations/{id}/products |
organizations.products.get | (organizationId, product: string) => Promise<OrganizationProductAccess> | GET /organizations/{id}/products/{product} |
organizations.products.checkEntitlement | (organizationId, product: string) => Promise<OrganizationProductEntitlementCheck> | GET /organizations/{id}/products/{product}/entitlement |
organizations.envVars.list | (organizationId, query?: ListQuery) => Promise<Paginated<EnvVar>> | GET /organizations/{id}/env-vars |
organizations.envVars.create | (organizationId, data: CreateEnvVarInput) => Promise<EnvVar> | POST /organizations/{id}/env-vars |
organizations.envVars.update | (organizationId, envVarId, data: UpdateEnvVarInput) => Promise<EnvVar> | PATCH /organizations/{id}/env-vars/{varId} |
organizations.envVars.delete | (organizationId, envVarId) => Promise<void> | DELETE /organizations/{id}/env-vars/{varId} |
Membership is read-only here, and so is product access: the SDK cannot add a member, change a role, or activate a plan. create needs a user-backed token with platform:organizations:write, and the caller becomes the owner.
const org = await client.organizations.create({ name: 'Acme Corp' });
const { items: members } = await client.organizations.members.list(org.id);
const { hasAccess } = await client.organizations.products.checkEntitlement(org.id, 'office');
console.log(`${members.length} members, office access: ${hasAccess}`);Applications
| Method | Signature | Endpoint |
|---|---|---|
applications.list | (query?: ListApplicationsQuery) => Promise<Paginated<Application>> | GET /applications |
applications.create | (input: CreateApplicationInput) => Promise<CreatedApplication> | POST /applications |
applications.hostnames | (applicationId: string) => Promise<ApplicationHostnameList> | GET /applications/{id}/hostnames |
applications.checkHostnameAvailability | (applicationId: string, label: string) => Promise<HostnameAvailability> | GET /applications/{id}/hostname/availability |
applications.setProductionHostname | (applicationId: string, label: string) => Promise<SetProductionHostnameResult> | PUT /applications/{id}/hostname |
applications.envVars.list | (applicationId, query?: ListQuery) => Promise<Paginated<EnvVar>> | GET /applications/{id}/env-vars |
applications.envVars.pull | (applicationId, query?: PullEnvVarsQuery) => Promise<PullEnvVarsResult> | GET /applications/{id}/env-vars/pull |
applications.envVars.create | (applicationId, data: CreateEnvVarInput) => Promise<EnvVar> | POST /applications/{id}/env-vars |
applications.envVars.update | (applicationId, envVarId, data: UpdateEnvVarInput) => Promise<EnvVar> | PATCH /applications/{id}/env-vars/{varId} |
applications.envVars.delete | (applicationId, envVarId) => Promise<void> | DELETE /applications/{id}/env-vars/{varId} |
applications.requests.list | (applicationId, query?: ListRequestsQuery) => Promise<Paginated<NetworkRequestSummary>> | GET /applications/{id}/requests |
applications.requests.get | (applicationId, requestId) => Promise<NetworkRequest> | GET /applications/{id}/requests/{requestId} |
There is no applications.get(id) and no applications.delete(id). Filter list by organizationId to narrow it down.
pull merges the organization, application and environment layers into the values a deployment would see, and it never returns a sensitive value. It reports how many it skipped as omittedSensitive, so a build script can fail loudly instead of booting with a missing secret:
const { items, omittedSensitive } = await client.applications.envVars.pull(applicationId, {
environment: 'production',
});
if (omittedSensitive > 0) {
throw new Error(`${omittedSensitive} sensitive variables were not returned`);
}
for (const variable of items) {
console.log(`${variable.key} (from ${variable.source})`);
}Request logs are filtered through ListRequestsQuery: from, to, method, status, statusFamily, hostname, pathPrefix, country, cacheStatus, cacheHit, deploymentId, plus limit and cursor. get returns the same record with sanitized request and response headers attached. Request logs explains what each field means.
Deployments
| Method | Signature | Endpoint |
|---|---|---|
deployments.list | (query?: ListDeploymentsQuery) => Promise<Paginated<Deployment>> | GET /deployments |
deployments.get | (deploymentId: string) => Promise<Deployment> | GET /deployments/{id} |
deployments.create | (data: CreateDeploymentInput) => Promise<Deployment> | POST /deployments |
deployments.startUpload | (deploymentId: string) => Promise<StartUploadResult> | POST /deployments/{id}/upload/start |
deployments.getPresignedUrl | (deploymentId, uploadId, partNumber: number) => Promise<PresignedUrlResult> | POST /deployments/{id}/upload/part |
deployments.uploadPart | (presignedUrl, data: ArrayBuffer | Uint8Array | Blob, partNumber) => Promise<UploadPart> | PUT to the presigned URL |
deployments.completeUpload | (deploymentId, uploadId, parts: UploadPart[]) => Promise<void> | POST /deployments/{id}/upload/complete |
deployments.getLogs | (deploymentId, query?: ListDeploymentLogsQuery) => Promise<DeploymentLogPage> | GET /deployments/{id}/logs |
deployments.getHostnames | (deploymentId: string) => Promise<Paginated<Hostname>> | GET /deployments/{id}/hostnames |
status moves through PENDING, QUEUED, STARTING, BUILDING, PROVISIONING, and ends at ACTIVE or FAILED. A deployment created from an uploaded archive stays PENDING until the upload completes.
Uploading an artifact runs through create, startUpload, one presigned PUT per part, and completeUpload. Parts are numbered from 1, every part is sent as application/zip, and each returns the ETag that completeUpload needs:
import { readFileSync } from 'node:fs';
import type { UploadPart } from '@gigadrive/sdk';
const archive = readFileSync('./build.zip');
const deployment = await client.deployments.create({ applicationId });
const { uploadId } = await client.deployments.startUpload(deployment.id);
const partSize = 10 * 1024 * 1024;
const parts: UploadPart[] = [];
for (let offset = 0, partNumber = 1; offset < archive.byteLength; offset += partSize, partNumber++) {
const { url } = await client.deployments.getPresignedUrl(deployment.id, uploadId, partNumber);
parts.push(await client.deployments.uploadPart(url, archive.subarray(offset, offset + partSize), partNumber));
}
await client.deployments.completeUpload(deployment.id, uploadId, parts);Build output arrives through getLogs, which pages by offset and limit rather than by cursor. Errors and pagination has a loop that tails a build to its final status.
Storage
Buckets are addressed by name, the immutable identifier that is unique within an environment. The global slug is for CDN and S3 delivery and is not accepted here; bucket UUIDs still work but are deprecated.
The bucket and object methods in this table also have older overloads that take an application ID as the first argument. Set applicationId on the client, or run inside a Function, and you can omit it.
| Method | Signature | Endpoint |
|---|---|---|
storage.buckets.list | (query?: ListStorageBucketsQuery) => Promise<Paginated<StorageBucket>> | GET .../storage/buckets |
storage.buckets.create | (data: CreateStorageBucketInput) => Promise<StorageBucket> | POST .../storage/buckets |
storage.buckets.get | (bucketRef, options?: StorageEnvironmentOptions) => Promise<StorageBucket> | GET .../buckets/{bucket} |
storage.buckets.delete | (bucketRef, options?: StorageEnvironmentOptions) => Promise<void> | DELETE .../buckets/{bucket} |
storage.objects.list | (bucketRef, query?: ListStorageObjectsQuery) => Promise<StorageObjectList> | GET .../buckets/{bucket}/objects |
storage.objects.get | (bucketRef, objectId, options?) => Promise<StorageObject> | GET .../objects/{objectId} |
storage.objects.getByKey | (bucketRef, key, options?) => Promise<StorageObject | null> | pages a prefix listing |
storage.objects.delete | (bucketRef, objectId, options?) => Promise<void> | DELETE .../objects/{objectId} |
storage.objects.getAccessUrl | (bucketRef, objectId, options?: StorageObjectAccessOptions) => Promise<StorageObjectAccess> | GET .../objects/{objectId}/access-url |
storage.trash.list | (bucketRef, query?: ListStorageTrashQuery) => Promise<StorageTrashList> | GET .../buckets/{bucket}/trash |
storage.trash.restore | (bucketRef, objectId, options?) => Promise<StorageObject> | POST .../trash/{objectId}/restore |
storage.trash.purge | (bucketRef, objectId, options?) => Promise<void> | DELETE .../trash/{objectId} |
storage.trash.empty | (bucketRef, options?) => Promise<EmptyStorageTrashResult> | DELETE .../buckets/{bucket}/trash |
objects.delete is a soft delete that moves the object to the bucket trash, where restore can bring it back and purge removes it for good. Deleting the bucket takes live and trashed objects with it. Trash and restore covers the retention side.
New buckets are private unless you say otherwise, and a private object needs a signed URL from getAccessUrl:
const bucket = await client.storage.buckets.create({
name: 'invoices',
environment: 'production',
visibility: 'private',
});
const { items, commonPrefixes } = await client.storage.objects.list(bucket.name, {
prefix: '2026/',
delimiter: '/',
});
for (const object of items) {
const { url, expiresAt } = await client.storage.objects.getAccessUrl(bucket.name, object.id, {
expiresInSeconds: 3600,
});
console.log(object.key, url, `expires ${expiresAt}`);
}
console.log('folders:', commonPrefixes);Sending bytes is a subject of its own, in Uploading files.
AI Gateway
| Method | Signature | Endpoint |
|---|---|---|
aiGateway.chatCompletions | (data: ChatCompletionRequest, options?) => Promise<ChatCompletionResponse> | POST /ai/v1/chat/completions |
aiGateway.chatCompletionsWithResponse | (data, options?) => Promise<GatewayResult<ChatCompletionResponse>> | POST /ai/v1/chat/completions |
aiGateway.chatCompletionsStream | (data, options?) => AsyncGenerator<ChatCompletionChunk> | POST /ai/v1/chat/completions |
aiGateway.responses | (data: ResponsesRequest, options?) => Promise<ResponsesResponse> | POST /ai/v1/responses |
aiGateway.responsesStream | (data, options?) => AsyncGenerator<unknown> | POST /ai/v1/responses |
aiGateway.listModels | () => Promise<Paginated<AiModel>> | GET /ai/v1/models |
aiGateway.getModel | (modelId: string) => Promise<AiModel> | GET /ai/v1/models/{id} |
aiGateway.audio.speech | (data: SpeechRequest, options?) => Promise<ArrayBuffer> | POST /ai/v1/audio/speech |
aiGateway.audio.transcriptions | (data: TranscriptionRequest, options?) => Promise<TranscriptionResponse> | POST /ai/v1/audio/transcriptions |
aiGateway.videos.generations | (data: VideoGenerationRequest, options?) => Promise<VideoGenerationResponse> | POST /ai/v1/videos |
aiGateway.videos.listModels | () => Promise<VideoModelList> | GET /ai/v1/videos/models |
chatCompletions forces stream: false and chatCompletionsStream forces stream: true, so the stream field you pass is ignored either way.
for await (const chunk of client.aiGateway.chatCompletionsStream({
model: 'openai/gpt-4o',
messages: [{ role: 'user', content: 'Write a haiku about the sea.' }],
})) {
process.stdout.write(chunk.choices[0]?.delta.content ?? '');
}Use chatCompletionsWithResponse when you want the response object alongside the body: it returns data, the raw response, and the requestId the gateway puts in the X-Gigadrive-Request-Id header. The result type also declares costMicros, which is always undefined, because no endpoint returns a cost header. Spend per request comes from Analytics.
Governance lives under the organization, and is separate from inference:
| Method | Signature | Endpoint |
|---|---|---|
organizations.aiGateway.usage.summary | (organizationId, query?: AiGatewayUsageQuery) => Promise<AiGatewayUsageSummary> | GET .../ai-gateway/usage/summary |
organizations.aiGateway.usage.requests | (organizationId, query?: AiGatewayRequestsQuery) => Promise<Paginated<AiGatewayRequestEvent>> | GET .../usage/requests |
organizations.aiGateway.usage.export | (organizationId, query?: AiGatewayRequestsQuery) => Promise<string> | GET .../usage/export |
organizations.aiGateway.budgets.list | (organizationId) => Promise<{ items: AiGatewayBudget[] }> | GET .../budgets |
organizations.aiGateway.budgets.replace | (organizationId, budgets: AiGatewayBudgetInput[]) => Promise<{ items: AiGatewayBudget[] }> | PUT .../budgets |
organizations.aiGateway.policies.get | (organizationId, options?: { applicationId?: string }) => Promise<AiGatewayPolicy | null> | GET .../policies |
organizations.aiGateway.policies.put | (organizationId, data: AiGatewayPolicyInput) => Promise<AiGatewayPolicy> | PUT .../policies |
budgets.replace overwrites the whole set. Passing [] clears every budget on the organization. usage.export returns CSV text rather than JSON.
API keys
| Method | Signature | Endpoint |
|---|---|---|
apiKeys.create | (data: CreateApiKeyInput) => Promise<CreateApiKeyResult> | POST /api-keys |
apiKeys.list | (query: ListApiKeysQuery) => Promise<Paginated<ApiKey>> | GET /api-keys |
apiKeys.delete | (apiKeyId: string) => Promise<void> | DELETE /api-keys/{id} |
Keys are application-scoped, so applicationId is required on both create and list. Requested scopes must be a subset of the scopes your own token carries, and a key cannot be granted API key management scopes.
const key = await client.apiKeys.create({
name: 'ci',
applicationId,
scopes: ['network:deployments:trigger', 'network:deployments:read'],
});
// key.secret is returned once and cannot be read again.
const ci = new GigadriveClient({ clientId: key.id, clientSecret: key.secret });Omit expiresAt and the key expires in 90 days.
Sticky sessions
| Method | Signature | Endpoint |
|---|---|---|
stickySessions.createUrl | (input: CreateStickySessionUrlInput) => Promise<CreateStickySessionUrlResult> | POST /sticky-sessions/urls |
A sticky URL routes every request that uses it to the same Function, which is what makes in-memory state such as a WebSocket room work. It is routing authority and not user authentication, so keep your own authorization checks. expiresInSeconds defaults to 14400 and accepts 60 to 86400.
const { url, expiresAt } = await client.stickySessions.createUrl({
key: 'room-42',
endpoint: '/socket',
expiresInSeconds: 3600,
});
console.log(`join at ${url}, valid until ${expiresAt}`);Only a Function may mint one, and only for its own deployment.
Image optimization
| Method | Signature | Endpoint |
|---|---|---|
createManagedImageUrl | (options: ManagedImageUrlOptions) => string | none, it builds a URL locally |
imageOptimization.url | (options: ManagedImageUrlOptions) => string | none, it builds a URL locally |
imageOptimization.inspect | (deploymentId: string, source?: string) => Promise<ImageCacheInspection> | GET /deployments/{id}/image-cache |
imageOptimization.purge | (deploymentId: string, source?: string) => Promise<ImageCachePurgeResult> | DELETE /deployments/{id}/image-cache |
createManagedImageUrl is exported from the package root, so a component can build image URLs without holding a client. purge with no source clears every optimized image in the deployment.
import { createManagedImageUrl } from '@gigadrive/sdk';
const src = createManagedImageUrl({
origin: 'https://acme.gigadrive.app',
source: '/photos/hero.jpg',
width: 1280,
format: 'avif',
quality: 80,
});