openapi: 3.0.0 info: version: 1.0.1-alpha1 termsOfService: https://exoscale.com/terms contact: email: api@exoscale.com name: API support url: https://community.exoscale.ch/support description: API for Partners, Distributors, and Marketplace vendors title: Exoscale Partner API tags: - description: The Metering API enables partners to send usage data for consolidated usage-based billing. externalDocs: description: Read more url: https://www.exoscale.com/partner-programs/ name: metering x-display-name: Metering x-weight: 100 x-icon: exo-logo - description: Provisioning and lifecycle management of end-customer organizations for members of the Exoscale distributor program. externalDocs: description: Read more url: https://www.exoscale.com/partner-programs/ name: distributor-organization x-display-name: Distributor organization x-weight: 200 x-icon: exo-logo components: schemas: usage-data: type: object properties: product: type: string description: Product name variable: type: string description: variable name quantity: type: number description: Usage quantity, unit is product dependent description: Usage data metering-batch: type: object properties: usage: type: array items: $ref: '#/components/schemas/usage-data' description: Usage data organization: type: string format: uuid description: Target Org description: A batch of metered usage quantities input-webhook-aiven: type: object properties: message_id: type: string format: uuid description: The UUID of the event. message_type: type: string description: The type of the event. metadata: type: object properties: graceful_promotion: type: boolean description: Whether the promotion was caused by a planned change of the master, or an unplanned promotion. username: type: string description: Username found in credentials leak database table_count: type: integer format: int64 description: A set of additional fields depend on the message type resource_type: type: string description: Automatic detection of the associated the resource type. service_type: type: string description: The type of the associated resource. more_info: type: string description: Short user-printable text describing the problem leak_url: type: string description: URL where the credential leak was found maintenance_scheduled_at: type: string description: Maintenance trigger deadline date users: type: array items: type: object properties: username: type: string old_cert_expiry_time: type: string description: Kafka service user certificates will expire soon and have been automatically renewed description: A set of additional fields depend on the message type project_name: type: string description: Name of the Aiven project that contains the service service_name: type: string description: Name of the Aiven service service_type: type: string description: Service type in a machine-readable format timestamp: type: integer format: int64 description: The timestamp of the event as Unix epoch required: - message_id - message_type description: A map representing the payload of Aiven webhooks. ok-map: type: object properties: ok: type: boolean billing-address: type: object properties: name: type: string minLength: 1 description: Name of the recipient. The organization's display name country: type: string maxLength: 2 minLength: 2 description: 'Country code. Format: ISO 3166-1 alpha-2' city: type: string maxLength: 255 minLength: 1 description: City name postal-code: type: string maxLength: 80 minLength: 1 description: Postal code street-name: type: string minLength: 1 description: Street name building-number: type: string maxLength: 255 description: Building number address: type: string minLength: 1 description: Free-text address fallback required: - name - country - city - postal-code - street-name description: ISO 20022 Structured Billing Address organization-input: type: object properties: display-name: type: string maxLength: 191 minLength: 1 description: Organization Display Name billing-address: $ref: '#/components/schemas/billing-address' description: ISO 20022 Structured Billing Address client-id: type: string maxLength: 191 description: Organization Client ID owner-email: type: string maxLength: 75 minLength: 1 writeOnly: true description: Email Address of the first Owner required: - display-name - billing-address - owner-email description: Organization creation request organization-output: type: object properties: id: type: string format: uuid readOnly: true description: Organization ID status: type: string enum: - created - suspended - active - terminated readOnly: true description: Organization Status billing-address: $ref: '#/components/schemas/billing-address' description: ISO 20022 Structured Billing Address client-id: type: string maxLength: 191 description: Organization Client ID description: Organization representation servers: - url: https://partner-api.exoscale.com/v1.alpha paths: /distributor/organization/{id}:schedule-purge: put: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: type: object properties: message: type: string description: The message indicating that the Organization has been successfully purged. "202": description: "202" content: application/json: schema: type: object properties: message: type: string description: The message indicating that the Organization has been successfully scheduled to be purged. description: Schedule the purge of an Organization linked to your Distributor Organization. parameters: - in: path required: true name: id schema: type: string format: uuid summary: "" operationId: schedule-purge-distributor-organization /metering:apply: post: tags: - metering responses: "204": description: "204" content: application/json: schema: $ref: '#/components/schemas/ok-map' description: |+ Submit usage metering for the given organization. The API accepts a set of `usage` entries. Each entry represents a product, its variable and a metering value. The value might be negative or decimal (up to five decimal places). Sample payload: ```json { 'usage': [ { 'product': 'partner', 'variable': 'license_product', 'quantity': 3.1415 }, { 'product': 'partner', 'variable': 'commission', 'quantity': -42.00005 } ], 'organization': 'bf9bbc88-71ea-407c-9920-fc1101d86183' } ``` parameters: [] summary: Apply metering transaction requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/metering-batch' operationId: metering-transaction /distributor/organization/{id}:suspend: put: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: $ref: '#/components/schemas/organization-output' description: Suspend an Organization linked to your Distributor Organization. parameters: - in: path required: true name: id schema: type: string format: uuid summary: "" operationId: suspend-distributor-organization /distributor/organization: post: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: $ref: '#/components/schemas/organization-output' description: Create an Organization linked to your Distributor Organization. parameters: [] summary: "" requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/organization-input' operationId: create-distributor-organization get: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: type: object properties: organizations: type: array items: $ref: '#/components/schemas/organization-output' description: The list of organizations. description: List Organizations linked to your Distributor Organization. parameters: [] summary: "" operationId: list-distributor-organizations /distributor/organization/{id}:terminate: delete: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: type: object properties: message: type: string description: The message indicating that the Organization has been successfully terminated. description: Terminate an Organization linked to your Distributor Organization. parameters: - in: path required: true name: id schema: type: string format: uuid summary: "" operationId: terminate-distributor-organization /distributor/organization/{id}/usage: get: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: type: array items: type: object properties: code: type: string description: Usage Code currency: type: string maxLength: 3 minLength: 3 description: 'Allowed values are: CHF, EUR, USD.' total-excl-vat: type: number description: Expressed in the currency of the Organization. total-incl-vat: type: number description: Expressed in the currency of the Organization. start-date: type: string format: date-time description: The start date for Usage statements end-date: type: string format: date-time description: The end date for Usage statements usage: type: array items: type: object properties: product: type: string description: The name of the product variable: type: string description: The variable of the product description: type: string description: Additional information about the usage statement quantity: type: number unit: type: string description: Unit used for this usage statement total-excl-vat: type: number description: The total amount of this Usage statement without VAT total-incl-vat: type: number description: The total amount of this Usage statement with VAT description: The usage statements description: List usage records of a sub-Organization. parameters: - in: path required: true name: id schema: type: string format: uuid - in: query required: false name: period schema: type: string maxLength: 7 minLength: 7 summary: "" operationId: list-distributor-organization-usage /distributor/organization/{id}:activate: put: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: $ref: '#/components/schemas/organization-output' description: Activate an Organization linked to your Distributor Organization. parameters: - in: path required: true name: id schema: type: string format: uuid summary: "" operationId: activate-distributor-organization /distributor/organization/{id}: get: tags: - distributor-organization responses: "200": description: "200" content: application/json: schema: $ref: '#/components/schemas/organization-output' description: Get an Organization linked to your Distributor Organization. parameters: - in: path required: true name: id schema: type: string format: uuid summary: "" operationId: get-distributor-organization x-topics: - title: API Request Signature content: | In order to authenticate legitimate users, the Exoscale API requires incoming requests to be signed using valid Exoscale API account credentials with the following mechanism. ## Signature Mechanism The *message* (i.e. content) to sign contains several segments concatenated using a line return character (`\n`). All segments must be included and in the described order, including empty ones depending on the context of the request (e.g. no request body). * Request method and request URL (path only), separated by a space character * Request body * Request URL parameters (Query String) values, concatenated without separator. The matching parameter names have to be specified in the resulting signature header `signed-query-args=` pragma, separated by semicolons (e.g. `p1;p2;pN`). * Request header values, concatenated without separator (none at the moment, leave empty) * Request expiration date in UNIX timestamp format Example *message* to sign for `GET /v2/resource/a02baf5a-a3e4-49a0-857b-8a08d276c1c0?p1=v1&p2=v2` : ``` GET /v2/resource/a02baf5a-a3e4-49a0-857b-8a08d276c1c0 v1v2 1599140767 ``` The request signature consists of the [HMAC][hmac] hash of the base64-encoded *message* and the Exoscale API secret using the SHA265 function: ``` signature = HMAC_SHA256(Exoscale API secret, BASE64_ENCODE(message)) ``` Finally, the computed signature must be added to the API request in a `Authorization` header such as: ``` Authorization: EXO2-HMAC-SHA256 credential=,expires=,signature= ``` Example API query: ``` GET /v2/resource/a02baf5a-a3e4-49a0-857b-8a08d276c1c0?p1=v1&p2=v2 HTTP/1.1 Host: api-ch-gva-2.exoscale.com Authorization: EXO2-HMAC-SHA256 credential=EXO29147e9f89102b7ac1e88514,signed-query-args=p1;p2,expires=1599140767,signature=2AOBQsbElQb4FpKT/FM/9T4NobjlmZkSGvvdUth/xlY= ``` ## Reference Implementations You can look up the following existing reference implementations: * Go: [github.com/exoscale/egoscale/api/v2 > `SecurityProviderExoscale.signRequest`](https://github.com/exoscale/egoscale/blob/master/v2/api/security.go) * Python: [requests-exoscale-auth > `ExoscaleV2Auth`](https://github.com/exoscale/requests-exoscale-auth/blob/master/exoscale_auth.py) [hmac]: https://en.wikipedia.org/wiki/HMAC