ControlUp Subscriptions API
The Subscriptions API from ControlUp — 27 operation(s) for subscriptions.
The Subscriptions API from ControlUp — 27 operation(s) for subscriptions.
openapi: 3.2.0
info:
title: DaaS IQ Subscriptions API
description: 'Multi-cloud Virtual Desktop Infrastructure Management API (Default Version: v1.0)
🔒 **Authentication**
This API supports two authentication methods:
**1. API Key (Bearer Token)** - Recommended for programmatic access
- Create an API key at [API Key Management](https://support.controlup.com/docs/create-an-api-key)
- Include in requests: `Authorization: Bearer YOUR_API_KEY`
**2. Cookie Authentication** - For browser-based access
- Login via DEX authentication service
- The `user_dex_token` cookie will be automatically included'
contact:
name: ControlUp Support
url: https://controlup.com/support
email: support@controlup.com
version: v1
x-build-version: 1.0.107
servers:
- url: https://api.controlup.com/daas-iq/v1
tags:
- name: Subscriptions
paths:
/cloud/subscriptions/{id}/credentials/verify:
post:
tags:
- Subscriptions
summary: Verify subscription credentials (Deprecated)
description: "\n<b>DEPRECATED:</b> Use POST /api/v1/cloud/tenants/{tenantId}/credentials/{credentialId}/verify to verify tenant credentials instead.\n Verifies cloud provider credentials and permissions synchronously. Check the IsSuccess field to determine if credentials are valid."
operationId: VerifySubscriptionCredentials
parameters:
- name: id
in: path
description: The unique subscription identifier.
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Verification completed.
content:
application/json:
schema:
$ref: '#/components/schemas/VerificationResponse'
example:
isSuccess: true
steps:
- stepName: Authenticating with Azure AD
status: success
isSuccess: true
durationMs: 450
- stepName: Listing subscriptions
status: success
isSuccess: true
durationMs: 320
- stepName: Checking subscription access
status: success
isSuccess: true
durationMs: 180
- stepName: Verifying Reader role
status: warning
detail: Role verification not fully implemented
isSuccess: false
durationMs: 220
completedAt: '2025-10-09T14:30:00Z'
durationMs: 1170
'400':
description: Bad request. Invalid subscription ID format.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized. User is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Payment required. No active license for the organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden. User does not have permission to view subscriptions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The specified subscription does not exist.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: Service unavailable. License status could not be verified. Try again later.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
deprecated: true
security:
- BearerAuth: []
- CookieAuth: []
/cloud/subscriptions/{id}/credentials/verify/transcript:
post:
tags:
- Subscriptions
summary: Verify subscription credentials - transcript (Deprecated)
description: "\n<b>DEPRECATED:</b> Use POST /api/v1/cloud/tenants/{tenantId}/credentials/{credentialId}/verify/transcript instead.\n Verifies the connection and permissions with formatted output lines. Check IsSuccess field for result."
operationId: VerifySubscriptionCredentialsTranscript
parameters:
- name: id
in: path
description: The unique subscription identifier.
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Verification completed.
content:
application/json:
schema:
$ref: '#/components/schemas/VerificationTranscriptResponse'
example:
isSuccess: true
output:
- -- Running validations --
- ' Authenticating with Azure AD ...... Success ✓'
- ' Listing subscriptions ............. Success ✓'
- ' Checking subscription access ...... Success ✓'
- ' Verifying Reader role ............. Success ✓'
- -- Validation success --
'400':
description: Bad request. Invalid subscription ID.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized. User is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Payment required. No active license for the organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden. User does not have subscription management permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The specified subscription does not exist.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: Service unavailable. License status could not be verified. Try again later.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
deprecated: true
security:
- BearerAuth: []
- CookieAuth: []
/cloud/subscriptions/{id}/credentials/verify/stream:
get:
tags:
- Subscriptions
summary: Verify subscription credentials - streaming (Deprecated)
description: "Streams real-time cloud credentials verification progress over a WebSocket connection using structured JSON messages.\nAll messages are serialized as JSON with camelCase property names and inherit from ControlUp.Foundry.Domain.Models.Verification.Messages.VerificationMessage.\n \n**Message Types (see Domain.Models.Verification.Messages namespace):**\n- ControlUp.Foundry.Domain.Models.Verification.Messages.VerificationStartedMessage: Verification process begins\n - Properties: `type`, `timestamp`\n \n- ControlUp.Foundry.Domain.Models.Verification.Messages.StepStartedMessage: A verification step begins\n - Properties: `type`, `timestamp`, `stepNumber`, `stepName`\n \n- ControlUp.Foundry.Domain.Models.Verification.Messages.StepCompletedMessage: A verification step completes\n - Properties: `type`, `timestamp`, `stepNumber`, `stepName`, `status`, `duration`, `detail`\n - `status` values: \"success\" | \"warning\" | \"failure\"\n \n- ControlUp.Foundry.Domain.Models.Verification.Messages.VerificationCompletedMessage: Verification process ends\n - Properties: `type`, `timestamp`, `success`, `duration`, `errorMessage`\n \n**Usage Flow:**\n1. Client establishes WebSocket connection to `/api/v1/cloud/subscriptions/{id}/credentials/verify/stream`\n2. Server validates subscription exists and user has permission\n3. Server accepts WebSocket connection (HTTP 101 Switching Protocols)\n4. Server sends ControlUp.Foundry.Domain.Models.Verification.Messages.VerificationStartedMessage\n5. For each verification step (provider-specific):\n - Server sends ControlUp.Foundry.Domain.Models.Verification.Messages.StepStartedMessage\n - Server performs verification against cloud provider API\n - Server sends ControlUp.Foundry.Domain.Models.Verification.Messages.StepCompletedMessage with results\n6. Server sends ControlUp.Foundry.Domain.Models.Verification.Messages.VerificationCompletedMessage\n7. Server closes WebSocket with normal closure or error status\n \n**WebSocket Client Example (JavaScript):**\n```javascript\nconst subscriptionId = '123e4567-e89b-12d3-a456-426614174000';\nconst ws = new WebSocket(`wss://api.example.com/api/v1/cloud/subscriptions/${subscriptionId}/credentials/verify/stream`);\n \nws.onopen = () => {\n console.log('WebSocket connected - waiting for verification to start...');\n};\n \nws.onmessage = (event) => {\n const message = JSON.parse(event.data);\n \n switch(message.type) {\n case 'verification_started':\n console.log('Verification started at:', message.timestamp);\n // Initialize UI for verification progress\n break;\n \n case 'step_started':\n console.log(`Step ${message.stepNumber}: ${message.stepName} - started`);\n // Show spinner/progress indicator for this step\n break;\n \n case 'step_completed':\n console.log(`Step ${message.stepNumber}: ${message.stepName} - ${message.status} in ${message.duration}`);\n if (message.detail) {\n console.log(` Detail: ${message.detail}`);\n }\n // Update UI with status icon: ✓ (success), ⚠ (warning), ✗ (failure)\n break;\n \n case 'verification_completed':\n console.log(`Verification ${message.success ? 'succeeded' : 'failed'} - Duration: ${message.duration}`);\n if (message.errorMessage) {\n console.error(`Error: ${message.errorMessage}`);\n }\n // Finalize UI with overall result\n break;\n \n default:\n console.warn('Unknown message type:', message.type);\n }\n};\n \nws.onerror = (error) => {\n console.error('WebSocket error:', error);\n // Handle connection errors\n};\n \nws.onclose = (event) => {\n console.log(`WebSocket closed - Code: ${event.code}, Reason: ${event.reason}`);\n // Clean up UI and resources\n};\n```\n \n**Example Message Sequence (Azure Subscription):**\n```json\n{\"type\":\"verification_started\",\"timestamp\":\"2025-10-23T10:30:00.000Z\"}\n{\"type\":\"step_started\",\"stepNumber\":1,\"stepName\":\"Validating Azure credentials format\",\"timestamp\":\"2025-10-23T10:30:00.100Z\"}\n{\"type\":\"step_completed\",\"stepNumber\":1,\"stepName\":\"Validating Azure credentials format\",\"status\":\"success\",\"duration\":\"00:00:00.150\",\"timestamp\":\"2025-10-23T10:30:00.250Z\"}\n{\"type\":\"step_started\",\"stepNumber\":2,\"stepName\":\"Testing connectivity to Azure Resource Manager\",\"timestamp\":\"2025-10-23T10:30:00.300Z\"}\n{\"type\":\"step_completed\",\"stepNumber\":2,\"stepName\":\"Testing connectivity to Azure Resource Manager\",\"status\":\"success\",\"duration\":\"00:00:01.200\",\"detail\":\"Successfully authenticated with tenant ID: abc123\",\"timestamp\":\"2025-10-23T10:30:01.500Z\"}\n{\"type\":\"step_started\",\"stepNumber\":3,\"stepName\":\"Verifying required Azure permissions\",\"timestamp\":\"2025-10-23T10:30:01.550Z\"}\n{\"type\":\"step_completed\",\"stepNumber\":3,\"stepName\":\"Verifying required Azure permissions\",\"status\":\"failure\",\"duration\":\"00:00:00.800\",\"detail\":\"Missing required role: Virtual Machine Contributor\",\"timestamp\":\"2025-10-23T10:30:02.350Z\"}\n{\"type\":\"verification_completed\",\"success\":false,\"duration\":\"00:00:02.500\",\"errorMessage\":\"Verification failed\",\"timestamp\":\"2025-10-23T10:30:02.500Z\"}\n```\n \n**Notes:**\n- All timestamps are in ISO 8601 UTC format\n- Duration fields are in TimeSpan format (hh:mm:ss.fffffff)\n- Step numbers are sequential, starting from 1\n- The `detail` field in ControlUp.Foundry.Domain.Models.Verification.Messages.StepCompletedMessage is optional (null for success, may contain info for warnings/failures)\n- WebSocket closes automatically after sending ControlUp.Foundry.Domain.Models.Verification.Messages.VerificationCompletedMessage\n- If an error occurs during verification, the server will attempt to close the WebSocket with appropriate status code"
parameters:
- name: id
in: path
description: The unique cloud subscription identifier.
required: true
schema:
type: string
format: uuid
responses:
'101':
description: Switching Protocols - WebSocket connection established.
'200':
description: OK
'400':
description: Bad request. Invalid subscription ID or not a WebSocket request.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized. User is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Payment required. No active license for the organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden. User does not have permission to view subscriptions in this organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The specified cloud subscription does not exist or does not belong to the current organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error occurred during verification.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: Service unavailable. License status could not be verified. Try again later.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
deprecated: true
security:
- BearerAuth: []
- CookieAuth: []
/cloud/subscriptions/{id}/credentials/verify/sse:
post:
tags:
- Subscriptions
summary: Verify subscription credentials - streaming (Deprecated)
description: '**DEPRECATED:** Use tenant-based credential verification endpoints instead.
SSE replacement for the WebSocket `/verify/stream` endpoint. Same message format, simpler protocol.'
parameters:
- name: id
in: path
description: The unique subscription identifier.
required: true
schema:
type: string
format: uuid
responses:
'200':
description: SSE stream started successfully.
'400':
description: Bad request. Invalid tenant ID or tenant has no default credential.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized. User is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Payment required. No active license for the organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden. User does not have view tenants permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The specified tenant does not exist.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error occurred during verification.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: Service unavailable. License status could not be verified. Try again later.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
deprecated: true
security:
- BearerAuth: []
- CookieAuth: []
/cloud/subscriptions/{subscriptionId}/metadata/regions:
get:
tags:
- Subscriptions
summary: Get available regions for a subscription
description: 'Returns the regions the subscription can deploy into, paginated, filterable and sortable.
Region identity and display names only — availability zones are omitted here and available per region from the single-region lookup.'
operationId: GetRegions
parameters:
- name: subscriptionId
in: path
description: The subscription ID.
required: true
schema:
type: string
format: uuid
- name: filter
in: query
description: 'Optional filter expression.
Supports JSON and RQL formats:
- JSON: {"and":[{"field":"status","op":"eq","value":"Active"},{"field":"name","op":"ct","value":"Smith, John"}]}
- RQL: and(eq(status,Active),ct(name,Smith%2C%20John)) — values are URL-decoded; encode reserved characters
Operators:
and, or, not (logical); eq, neq, ct, nct, sw, nsw, ew, new, gt, gte, lt, lte (predicate)
Fields (names are matched case-insensitively):
displayName, geography, isPhysical, name, regionalDisplayName, regionCategory'
schema:
type: string
examples:
json:
summary: json
value: '{"field":"name","op":"eq","value":"value"}'
rql:
summary: rql
value: eq(name,value)
x-foundry-filter:
fields:
- displayName
- geography
- isPhysical
- name
- regionalDisplayName
- regionCategory
operators:
logical:
- and
- or
- not
predicate:
- eq
- neq
- ct
- nct
- sw
- nsw
- ew
- new
- gt
- gte
- lt
- lte
dynamicPaths: false
- name: sort
in: query
description: 'Sort expression for ordering results.
Format:
field:direction,otherField:direction
Directions: asc, desc, ascending, descending — defaults to ascending when omitted
Fields (names are matched case-insensitively):
displayName, geography, isPhysical, name, regionalDisplayName, regionCategory
Default when omitted: displayName:asc.'
schema:
type: string
examples:
default:
summary: default
value: displayName:asc
x-foundry-sort:
fields:
- displayName
- geography
- isPhysical
- name
- regionalDisplayName
- regionCategory
dynamicPaths: false
defaultField: displayName
defaultAscending: true
- name: page
in: query
description: 'The page number to retrieve (1-based). Default: 1.'
schema:
maximum: 2147483647
minimum: 1
type: integer
format: int32
- name: pageSize
in: query
description: 'The number of items per page (1-100). Default: 50.'
schema:
maximum: 100
minimum: 1
type: integer
format: int32
responses:
'200':
description: Successfully retrieved regions.
content:
application/json:
schema:
$ref: '#/components/schemas/RegionMetadataDtoPagedResultDto'
'400':
description: Bad request. Invalid subscription ID or filter/sort parameters.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized. User is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Payment required. No active license for the organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden. User does not have view subscriptions permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The specified subscription does not exist.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: Service unavailable. License status could not be verified. Try again later.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
security:
- BearerAuth: []
- CookieAuth: []
/cloud/subscriptions/{subscriptionId}/metadata/regions/{region}:
get:
tags:
- Subscriptions
summary: Get region metadata
description: 'Returns one named region''s metadata in the subscription''s context, including the availability zones that the region list omits.
Describes a single region rather than enumerating which regions are available.'
operationId: GetRegionMetadata
parameters:
- name: subscriptionId
in: path
description: The subscription ID.
required: true
schema:
type: string
format: uuid
- name: region
in: path
description: Region code.
required: true
schema:
type: string
responses:
'200':
description: Successfully retrieved region metadata.
content:
application/json:
schema:
$ref: '#/components/schemas/RegionMetadataDto'
'400':
description: Bad request. Subscription ID is invalid or region is missing or blank.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized. User is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Payment required. No active license for the organization.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden. User does not have view subscriptions permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The specified subscription or region does not exist.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: Service unavailable. License status could not be verified. Try again later.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
security:
- BearerAuth: []
- CookieAuth: []
/cloud/subscriptions/{subscriptionId}/metadata/vm-sizes:
get:
tags:
- Subscriptions
summary: Get available VM sizes for a region with filtering, sorting, and pagination support
description: 'Returns the VM SKUs offered in a region with full specifications: CPU count, memory, disk limits, IOPS, and capability flags.
Describes what each SKU is capable of, not whether the subscription has quota left to deploy one.
Supports filtering, sorting, and pagination for large result sets.'
operationId: GetVmSizes
parameters:
- name: subscriptionId
in: path
description: The subscription ID.
required: true
schema:
type: string
format: uuid
- name: region
in: query
description: 'Azure region/location (e.g., "eastus", "westeurope").
Required.'
required: true
schema:
maxLength: 64
type: string
- name: filter
in: query
description: 'Optional filter expression.
Supports JSON and RQL formats:
- JSON: {"and":[{"field":"status","op":"eq","value":"Active"},{"field":"name","op":"ct","value":"Smith, John"}]}
- RQL: and(eq(status,Active),ct(name,Smith%2C%20John)) — values are URL-decoded; encode reserved characters
Operators:
and, or, not (logical); eq, neq, ct, nct, sw, nsw, ew, new, gt, gte, lt, lte (predicate)
Fields (names are matched case-insensitively):
cores, cpuArchitectureType, displayName, family, isRestricted, localStorageBytes, maxDataDisks, maxIops, maxNetworkInterfaces, memoryBytes, name, osDiskSizeBytes, size, supportsAcceleratedNetworking, supportsDiskControllerNVMe, supportsDiskControllerSCSI, supportsEphemeralOSDisk, supportsHyperVGenerationV1, supportsHyperVGenerationV2, supportsPremiumStorage, supportsTrustedLaunch, tier'
schema:
type: string
examples:
json:
summary: json
value: '{"field":"name","op":"eq","value":"value"}'
rql:
summary: rql
value: eq(name,value)
x-foundry-filter:
fields:
- cores
- cpuArchitectureType
- displayName
- family
- isRestricted
- localStorageBytes
- maxDataDisks
- maxIops
- maxNetworkInterfaces
- memoryBytes
- name
- osDiskSizeBytes
- size
- supportsAcceleratedNetworking
- supportsDiskControllerNVMe
- supportsDiskControllerSCSI
- supportsEphemeralOSDisk
- supportsHyperVGenerationV1
- supportsHyperVGenerationV2
- supportsPremiumStorage
- supportsTrustedLaunch
- tier
operators:
logical:
- and
- or
- not
predicate:
- eq
- neq
- ct
- nct
- sw
- nsw
- ew
- new
- gt
- gte
- lt
- lte
dynamicPaths: false
- name: sort
in: query
description: 'Sort expression for ordering results.
Format:
field:direction,otherField:direction
Directions: asc, desc, ascending, descending — defaults to ascending when omitted
Fields (names are matched case-insensitively):
cores, cpuArchitectureType, displayName, family, isRestricted, localStorageBytes, maxDataDisks, maxIops, maxNetworkInterfaces, memoryBytes, name, osDiskSizeBytes, size, supportsAcceleratedNetworking, supportsDiskControllerNVMe, supportsDiskControllerSCSI, supportsEphemeralOSDisk, supportsHyperVGenerationV1, supportsHyperVGenerationV2, supportsPremiumStorage, supportsTrustedLaunch, tier
Default when omitted: name:asc.'
schema:
type: string
examples:
default:
summary: default
value: name:asc
x-foundry-sort:
fields:
- cores
- cpuArchitectureType
- displayName
- family
- isRestricted
- localStorageBytes
- maxDataDisks
- maxIops
- maxNetworkInterfaces
- memoryBytes
- name
- osDiskSizeBytes
- size
- supportsAcceleratedNetworking
- supportsDiskControllerNVMe
- supportsDiskControllerSCSI
- supportsEphemeralOSDisk
- supportsHyperVGenerationV1
- supportsHyperVGenerationV2
- supportsPremiumStorage
- supportsTrustedLaunch
- tier
dynamicPaths: false
defaultField: name
defaultAscending: true
- name: page
in: query
description: 'The page number to retrieve (1-based). Default: 1.'
schema:
maximum: 2147483647
minimum: 1
type: integer
format: int32
- name: pageSize
in: query
description: 'The number of items per page (1-100). Default: 50.'
schema:
maximum: 100
minimum: 1
type: integer
format: int32
responses:
'200':
description: Successfully retrieved VM sizes.
content:
application/json:
schema:
$ref: '#/components/schemas/VmSizeDtoPagedResultDto'
example:
items:
- name: Standard_D2s_v5
displayName: Standard D2s_v5
tier: Standard
size: D2s_v5
cores: 2
memoryBytes: 8589934592
maxDataDisks: 4
osDiskSizeBytes: 1098437885952
localStorageBytes: 0
family: standardDSv5Family
maxIops: 3750
maxNetworkInterfaces: 2
supportsPremiumStorage: true
supportsAcceleratedNetworking: true
supportsEphemeralOSDisk: true
supportsTrustedLaunch: true
availableZones:
- '1'
- '2'
- '3'
hyperVGenerations:
- V1
- V2
diskControllerTypes:
- SCSI
cpuArchitectureType: x64
supportsHyperVGenerationV1: true
supportsHyperVGenerationV2: true
supportsDiskControllerSCSI: true
supportsDiskControllerNVMe: false
isRestricted: false
- name: Standard_D2s_v6
displayName: Standard D2s_v6
tier: Standard
size: D2s_v6
cores: 2
memoryBytes: 8589934592
# --- truncated at 32 KB (227 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/controlup/refs/heads/main/openapi/controlup-subscriptions-api-openapi.yml