diff --git a/.stats.yml b/.stats.yml
index bbef6e28..c59f8103 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 93
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-94ab316666bc8401703576710fe5ef92b9bd7ca34e5eb6b0cc6ef44060afd4f5.yml
+configured_endpoints: 94
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-ed05a916073da77a6014b00356582dee89a933b8fdba6370fa53767338516e45.yml
diff --git a/api.md b/api.md
index edaa2837..c5523a34 100644
--- a/api.md
+++ b/api.md
@@ -170,6 +170,16 @@ Methods:
- client.events.backfills.fetch(backfillId) -> BackfillFetchResponse
- client.events.backfills.revert(backfillId) -> BackfillRevertResponse
+## Volume
+
+Types:
+
+- EventVolumes
+
+Methods:
+
+- client.events.volume.list({ ...params }) -> EventVolumes
+
# InvoiceLineItems
Types:
diff --git a/src/resources/events/events.ts b/src/resources/events/events.ts
index 2f83ca18..5b5f94b1 100644
--- a/src/resources/events/events.ts
+++ b/src/resources/events/events.ts
@@ -4,9 +4,11 @@ import { APIResource } from '../../resource';
import * as Core from '../../core';
import * as EventsAPI from './events';
import * as BackfillsAPI from './backfills';
+import * as VolumeAPI from './volume';
export class Events extends APIResource {
backfills: BackfillsAPI.Backfills = new BackfillsAPI.Backfills(this._client);
+ volume: VolumeAPI.Volume = new VolumeAPI.Volume(this._client);
/**
* This endpoint is used to amend a single usage event with a given `event_id`.
@@ -577,4 +579,7 @@ export namespace Events {
export import BackfillListResponsesPage = BackfillsAPI.BackfillListResponsesPage;
export import BackfillCreateParams = BackfillsAPI.BackfillCreateParams;
export import BackfillListParams = BackfillsAPI.BackfillListParams;
+ export import Volume = VolumeAPI.Volume;
+ export import EventVolumes = VolumeAPI.EventVolumes;
+ export import VolumeListParams = VolumeAPI.VolumeListParams;
}
diff --git a/src/resources/events/index.ts b/src/resources/events/index.ts
index 05e63bf1..4e7c3138 100644
--- a/src/resources/events/index.ts
+++ b/src/resources/events/index.ts
@@ -21,3 +21,4 @@ export {
EventSearchParams,
Events,
} from './events';
+export { EventVolumes, VolumeListParams, Volume } from './volume';
diff --git a/src/resources/events/volume.ts b/src/resources/events/volume.ts
new file mode 100644
index 00000000..2d028a42
--- /dev/null
+++ b/src/resources/events/volume.ts
@@ -0,0 +1,90 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../resource';
+import { isRequestOptions } from '../../core';
+import * as Core from '../../core';
+import * as VolumeAPI from './volume';
+
+export class Volume extends APIResource {
+ /**
+ * This endpoint returns the event volume for an account in a
+ * [paginated list format](../reference/pagination).
+ *
+ * The event volume is aggregated by the hour and the
+ * [timestamp](../reference/ingest#determining-event-timestamp) field is used to
+ * determine which hour an event is associated with. Note, this means that
+ * late-arriving events increment the volume count for the hour window the
+ * timestamp is in, not the latest hour window.
+ *
+ * Each item in the response contains the count of events aggregated by the hour
+ * where the start and end time are hour-aligned and in UTC. When a specific
+ * timestamp is passed in for either start or end time, the response includes the
+ * hours the timestamp falls in.
+ */
+ list(query?: VolumeListParams, options?: Core.RequestOptions): Core.APIPromise;
+ list(options?: Core.RequestOptions): Core.APIPromise;
+ list(
+ query: VolumeListParams | Core.RequestOptions = {},
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ if (isRequestOptions(query)) {
+ return this.list({}, query);
+ }
+ return this._client.get('/events/volume', { query, ...options });
+ }
+}
+
+export interface EventVolumes {
+ data: Array;
+}
+
+export namespace EventVolumes {
+ /**
+ * An EventVolume contains the event volume ingested in an hourly window. The
+ * timestamp used for the aggregation is the `timestamp` datetime field on events.
+ */
+ export interface Data {
+ /**
+ * The number of events ingested with a timestamp between the timeframe
+ */
+ count: number;
+
+ timeframe_end: string;
+
+ timeframe_start: string;
+ }
+}
+
+export interface VolumeListParams {
+ /**
+ * Cursor for pagination. This can be populated by the `next_cursor` value returned
+ * from the initial request.
+ */
+ cursor?: string | null;
+
+ /**
+ * The number of items to fetch. Defaults to 20.
+ */
+ limit?: number;
+
+ /**
+ * The end of the timeframe, exclusive, in which to return event volume. If not
+ * specified, the current time is used. All datetime values are converted to UTC
+ * time.If the specified time isn't hour-aligned, the response includes the event
+ * volumecount for the hour the time falls in.
+ */
+ timeframe_end?: string;
+
+ /**
+ * The start of the timeframe, inclusive, in which to return event volume. All
+ * datetime values are converted to UTC time. If the specified time isn't
+ * hour-aligned, the response includes the event volume count for the hour the time
+ * falls in.
+ */
+ timeframe_start?: string;
+}
+
+export namespace Volume {
+ export import EventVolumes = VolumeAPI.EventVolumes;
+ export import VolumeListParams = VolumeAPI.VolumeListParams;
+}
diff --git a/tests/api-resources/events/volume.test.ts b/tests/api-resources/events/volume.test.ts
new file mode 100644
index 00000000..495cbefd
--- /dev/null
+++ b/tests/api-resources/events/volume.test.ts
@@ -0,0 +1,44 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Orb from 'orb-billing';
+import { Response } from 'node-fetch';
+
+const client = new Orb({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource volume', () => {
+ test('list', async () => {
+ const responsePromise = client.events.volume.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('list: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.events.volume.list({ path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Orb.NotFoundError,
+ );
+ });
+
+ test('list: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.events.volume.list(
+ {
+ cursor: 'cursor',
+ limit: 1,
+ timeframe_end: '2019-12-27T18:11:19.117Z',
+ timeframe_start: '2019-12-27T18:11:19.117Z',
+ },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(Orb.NotFoundError);
+ });
+});