-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat:Expand OpenAPI: management endpoints and spend-commit time fields #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdded new management API endpoints for API keys, organization member operations, profiles, and usage reporting to src/libs/Ideogram/openapi.yaml. Introduced/extended corresponding request/response schemas, enums, and examples. Updated spend-commit models to time-based fields and added is_postpaid_commit. No removals; all changes are additive. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant M as Manage API
participant A as Auth/Z
participant O as Org Service
C->>M: POST /organization/add_members (emails, roles)
M->>A: Validate token & org permissions
A-->>M: AuthZ OK/Fail
alt Authorized
M->>O: AddMembers(org_id, members)
O-->>M: 204 No Content
M-->>C: 204 No Content
else Unauthorized/Invalid
M-->>C: 400/401/403/404
end
sequenceDiagram
autonumber
participant C as Client
participant M as Manage API
participant A as Auth/Z
participant U as Usage Service
participant B as Billing/Commit
C->>M: GET /usage?org_id&segment_by&start_time&...
M->>A: Validate token & scope
A-->>M: OK/Fail
alt OK
M->>U: Query usage (filters, model_versions, tools, api_keys)
U->>B: Fetch spend commits (time-based)
B-->>U: Commit data (start_time/end_time, is_postpaid_commit)
U-->>M: Aggregated UsageSegments
M-->>C: 200 GetUsageInfoResponse
else Fail
M-->>C: 401/403
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/libs/Ideogram/openapi.yaml (1)
671-678: Fix spend-commit example timestamp formatting.Line [676] declares
commit_start_timeas'2025-01-01', but the schema advertises an RFC3339date-time. Please align the example with the declared format (e.g., include the time zone).- commit_start_time: '2025-01-01' + commit_start_time: '2025-01-01T00:00:00Z'
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (67)
src/libs/Ideogram/Generated/Ideogram..JsonSerializerContext.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.AddOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.CreateApiKeyV2.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.DeactivateOrganizationApiKey.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.GetApiProfiles.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.GetOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.GetUsageInfo.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.GetUserCredits.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.GetUserSpendCommitInfo.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.PromoteOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.IManageClient.RemoveOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ApiKeyStatus.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ApiKeyStatusNullable.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ApiProfileRole.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ApiProfileRoleNullable.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ApiProfileType.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ApiProfileTypeNullable.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ModelVersion.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ModelVersionNullable.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.SegmentBy.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.SegmentByNullable.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ToolType.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonConverters.ToolTypeNullable.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.JsonSerializerContextTypes.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.AddOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.CreateApiKeyV2.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.DeactivateOrganizationApiKey.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.GetApiProfiles.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.GetOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.GetUsageInfo.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.GetUserCredits.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.GetUserSpendCommitInfo.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.PromoteOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.ManageClient.RemoveOrganizationMembers.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.AddOrganizationMembersRequest.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.AddOrganizationMembersRequest.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ApiKeyStatus.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ApiProfile.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ApiProfile.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ApiProfileApiKey.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ApiProfileApiKey.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ApiProfileRole.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ApiProfileType.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.CreateApiKeyResponse.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.CreateApiKeyResponse.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.GetApiProfilesResponse.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.GetApiProfilesResponse.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.GetOrganizationMembersResponse.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.GetOrganizationMembersResponse.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.GetUsageInfoResponse.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.GetUsageInfoResponse.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.LiteOrganizationMember.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.LiteOrganizationMember.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ModelVersion.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.OrganizationMember.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.OrganizationMember.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.PromoteOrganizationMembersRequest.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.PromoteOrganizationMembersRequest.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.RemoveOrganizationMembersRequest.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.RemoveOrganizationMembersRequest.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.SegmentBy.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.SpendCommitInfo.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ToolType.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ToolUsage.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.ToolUsage.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.UsageSegment.Json.g.csis excluded by!**/generated/**src/libs/Ideogram/Generated/Ideogram.Models.UsageSegment.g.csis excluded by!**/generated/**
📒 Files selected for processing (1)
src/libs/Ideogram/openapi.yaml(7 hunks)
🧰 Additional context used
🪛 Checkov (3.2.334)
src/libs/Ideogram/openapi.yaml
[medium] 846-850: Ensure that arrays have a maximum number of items
(CKV_OPENAPI_21)
🪛 Gitleaks (8.28.0)
src/libs/Ideogram/openapi.yaml
[high] 3133-3133: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
| example: | ||
| usage_segments: | ||
| - segment_start: '2023-08-09' | ||
| segment_end: '2023-08-09T23:59:59.0000000+00:00' | ||
| tool_usage: | ||
| - full_tool_name: Turbo Image Generation V3 | ||
| amount: | ||
| currency_code: USD | ||
| amount: 1250 | ||
| - full_tool_name: Upscale Image V1 | ||
| amount: | ||
| currency_code: USD | ||
| amount: 750 | ||
| - full_tool_name: Balanced Edit Image V2 | ||
| amount: | ||
| currency_code: USD | ||
| amount: 500 | ||
| - segment_start: '2023-08-10' | ||
| segment_end: '2023-08-10T23:59:59.0000000+00:00' | ||
| tool_usage: | ||
| - full_tool_name: generate | ||
| amount: | ||
| currency_code: USD | ||
| amount: 2000 | ||
| '401': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align usage segment examples with date-time schema.
Lines [875] and [891] list segment_start using date-only strings even though the schema requires format: date-time. Update the examples so downstream tooling sees valid RFC3339 timestamps.
- - segment_start: '2023-08-09'
+ - segment_start: '2023-08-09T00:00:00Z'
...
- - segment_start: '2023-08-10'
+ - segment_start: '2023-08-10T00:00:00Z'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| example: | |
| usage_segments: | |
| - segment_start: '2023-08-09' | |
| segment_end: '2023-08-09T23:59:59.0000000+00:00' | |
| tool_usage: | |
| - full_tool_name: Turbo Image Generation V3 | |
| amount: | |
| currency_code: USD | |
| amount: 1250 | |
| - full_tool_name: Upscale Image V1 | |
| amount: | |
| currency_code: USD | |
| amount: 750 | |
| - full_tool_name: Balanced Edit Image V2 | |
| amount: | |
| currency_code: USD | |
| amount: 500 | |
| - segment_start: '2023-08-10' | |
| segment_end: '2023-08-10T23:59:59.0000000+00:00' | |
| tool_usage: | |
| - full_tool_name: generate | |
| amount: | |
| currency_code: USD | |
| amount: 2000 | |
| '401': | |
| example: | |
| usage_segments: | |
| - segment_start: '2023-08-09T00:00:00Z' | |
| segment_end: '2023-08-09T23:59:59.0000000+00:00' | |
| tool_usage: | |
| - full_tool_name: Turbo Image Generation V3 | |
| amount: | |
| currency_code: USD | |
| amount: 1250 | |
| - full_tool_name: Upscale Image V1 | |
| amount: | |
| currency_code: USD | |
| amount: 750 | |
| - full_tool_name: Balanced Edit Image V2 | |
| amount: | |
| currency_code: USD | |
| amount: 500 | |
| - segment_start: '2023-08-10T00:00:00Z' | |
| segment_end: '2023-08-10T23:59:59.0000000+00:00' | |
| tool_usage: | |
| - full_tool_name: generate | |
| amount: | |
| currency_code: USD | |
| amount: 2000 | |
| '401': |
🤖 Prompt for AI Agents
In src/libs/Ideogram/openapi.yaml around lines 873 to 897, the example shows
segment_start as date-only strings on lines 875 and 891 but the schema requires
RFC3339 date-time format; update those example values to full date-time strings
(e.g., "2023-08-09T00:00:00Z" and "2023-08-10T00:00:00Z" or equivalent with
offset) so they conform to format: date-time and downstream tooling validates
correctly.
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | ||
| redacted_api_key: ATG56••••••••••••• | ||
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | ||
| status: | ||
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | ||
| redacted_api_key: ATG56••••••••••••• | ||
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | ||
| status: | ||
| max_num_inflight_requests_permitted: 10 | ||
| - is_metronome_2_user: true | ||
| role: OWNER | ||
| avatar_url: https://example.com/avatar.jpg | ||
| organization_id: b3JnYW5pemF0aW9uXzEyMw | ||
| name: Gamma | ||
| type: INDIVIDUAL | ||
| api_keys: | ||
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | ||
| redacted_api_key: ATG56••••••••••••• | ||
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | ||
| status: | ||
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | ||
| redacted_api_key: ATG56••••••••••••• | ||
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | ||
| status: | ||
| max_num_inflight_requests_permitted: 10 | ||
| ApiProfile: | ||
| title: ApiProfile | ||
| required: | ||
| - api_keys | ||
| - avatar_url | ||
| - is_metronome_2_user | ||
| - max_num_inflight_requests_permitted | ||
| - name | ||
| - organization_id | ||
| - role | ||
| - type | ||
| type: object | ||
| properties: | ||
| type: | ||
| $ref: '#/components/schemas/ApiProfileType' | ||
| name: | ||
| title: name | ||
| type: string | ||
| description: The display name of the profile | ||
| example: Gamma | ||
| avatar_url: | ||
| title: avatar_url | ||
| type: string | ||
| description: URL to the profile avatar | ||
| example: https://example.com/avatar.jpg | ||
| organization_id: | ||
| title: organization_id | ||
| type: string | ||
| description: Base64 encoded organization ID (only for ENTERPRISE profiles) | ||
| example: b3JnYW5pemF0aW9uXzEyMw | ||
| role: | ||
| $ref: '#/components/schemas/ApiProfileRole' | ||
| api_keys: | ||
| title: api_keys | ||
| type: array | ||
| items: | ||
| $ref: '#/components/schemas/ApiProfileApiKey' | ||
| description: List of API keys associated with this profile | ||
| is_metronome_2_user: | ||
| title: is_metronome_2_user | ||
| type: boolean | ||
| description: Whether the user is on Metronome 2.0 | ||
| max_num_inflight_requests_permitted: | ||
| title: max_num_inflight_requests_permitted | ||
| type: integer | ||
| description: The maximum number of inflight requests permitted for the profile | ||
| example: 10 | ||
| example: | ||
| is_metronome_2_user: true | ||
| role: OWNER | ||
| avatar_url: https://example.com/avatar.jpg | ||
| organization_id: b3JnYW5pemF0aW9uXzEyMw | ||
| name: Gamma | ||
| type: INDIVIDUAL | ||
| api_keys: | ||
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | ||
| redacted_api_key: ATG56••••••••••••• | ||
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | ||
| status: | ||
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | ||
| redacted_api_key: ATG56••••••••••••• | ||
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | ||
| status: | ||
| max_num_inflight_requests_permitted: 10 | ||
| ApiProfileType: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Populate status with a valid enum value in the profile example.
Line [2904] leaves status blank, but ApiProfileApiKey.status is required and constrained to ACTIVE or DISABLED. Please set the example to one of those values so clients don’t infer that empty strings are acceptable.
- - creation_time: '2000-01-23T04:56:07.0000000+00:00'
- redacted_api_key: ATG56•••••••••••••
- api_key_id: JRPVD7jWR1aTBYiJ0UFVOg
- status:
+ - creation_time: '2000-01-23T04:56:07.0000000+00:00'
+ redacted_api_key: ATG56•••••••••••••
+ api_key_id: JRPVD7jWR1aTBYiJ0UFVOg
+ status: ACTIVE📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | |
| redacted_api_key: ATG56••••••••••••• | |
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | |
| status: | |
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | |
| redacted_api_key: ATG56••••••••••••• | |
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | |
| status: | |
| max_num_inflight_requests_permitted: 10 | |
| - is_metronome_2_user: true | |
| role: OWNER | |
| avatar_url: https://example.com/avatar.jpg | |
| organization_id: b3JnYW5pemF0aW9uXzEyMw | |
| name: Gamma | |
| type: INDIVIDUAL | |
| api_keys: | |
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | |
| redacted_api_key: ATG56••••••••••••• | |
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | |
| status: | |
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | |
| redacted_api_key: ATG56••••••••••••• | |
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | |
| status: | |
| max_num_inflight_requests_permitted: 10 | |
| ApiProfile: | |
| title: ApiProfile | |
| required: | |
| - api_keys | |
| - avatar_url | |
| - is_metronome_2_user | |
| - max_num_inflight_requests_permitted | |
| - name | |
| - organization_id | |
| - role | |
| - type | |
| type: object | |
| properties: | |
| type: | |
| $ref: '#/components/schemas/ApiProfileType' | |
| name: | |
| title: name | |
| type: string | |
| description: The display name of the profile | |
| example: Gamma | |
| avatar_url: | |
| title: avatar_url | |
| type: string | |
| description: URL to the profile avatar | |
| example: https://example.com/avatar.jpg | |
| organization_id: | |
| title: organization_id | |
| type: string | |
| description: Base64 encoded organization ID (only for ENTERPRISE profiles) | |
| example: b3JnYW5pemF0aW9uXzEyMw | |
| role: | |
| $ref: '#/components/schemas/ApiProfileRole' | |
| api_keys: | |
| title: api_keys | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ApiProfileApiKey' | |
| description: List of API keys associated with this profile | |
| is_metronome_2_user: | |
| title: is_metronome_2_user | |
| type: boolean | |
| description: Whether the user is on Metronome 2.0 | |
| max_num_inflight_requests_permitted: | |
| title: max_num_inflight_requests_permitted | |
| type: integer | |
| description: The maximum number of inflight requests permitted for the profile | |
| example: 10 | |
| example: | |
| is_metronome_2_user: true | |
| role: OWNER | |
| avatar_url: https://example.com/avatar.jpg | |
| organization_id: b3JnYW5pemF0aW9uXzEyMw | |
| name: Gamma | |
| type: INDIVIDUAL | |
| api_keys: | |
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | |
| redacted_api_key: ATG56••••••••••••• | |
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | |
| status: | |
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | |
| redacted_api_key: ATG56••••••••••••• | |
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | |
| status: | |
| max_num_inflight_requests_permitted: 10 | |
| ApiProfileType: | |
| - creation_time: '2000-01-23T04:56:07.0000000+00:00' | |
| redacted_api_key: ATG56••••••••••••• | |
| api_key_id: JRPVD7jWR1aTBYiJ0UFVOg | |
| status: ACTIVE |
🤖 Prompt for AI Agents
In src/libs/Ideogram/openapi.yaml around lines 2901-2990, the example ApiProfile
entries leave ApiProfileApiKey.status blank at line ~2904 (and the two other
example api_key entries later in the ApiProfile example); update those example
fields to a valid enum value (either ACTIVE or DISABLED) — e.g., replace the
empty status values with ACTIVE for each api_keys item so the OpenAPI example
conforms to the ApiProfileApiKey.required and enum constraints.
Summary by CodeRabbit
New Features
Documentation