{
  "openapi": "3.0.3",
  "info": {
    "title": "tronbase API",
    "version": "1.0.0",
    "description": "Rent TRON Energy and Bandwidth from an account balance. Amounts are whole SUN (1 TRX = 1,000,000 SUN). The prose version of these docs, with the webhook and idempotency rules, is at /api-docs.md.",
    "contact": {
      "name": "tronbase support",
      "email": "support@tronbase.io",
      "url": "https://tronbase.io"
    }
  },
  "servers": [
    {
      "url": "https://tronbase.io/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "Who the key belongs to and what it can spend."
    },
    {
      "name": "Orders",
      "description": "Buying energy and bandwidth."
    },
    {
      "name": "Automations",
      "description": "Standing orders that buy without being asked."
    },
    {
      "name": "Reference",
      "description": "Prices, addresses and the documentation itself."
    }
  ],
  "paths": {
    "/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "The account behind the key",
        "description": "Who owns the key, the balance in SUN, the deposit address, and the webhooks registered on the account.",
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "The account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "email": {
                          "type": "string",
                          "format": "email"
                        },
                        "balanceSun": {
                          "type": "integer"
                        },
                        "depositAddress": {
                          "type": "string",
                          "nullable": true
                        },
                        "webhooks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "integer"
                              },
                              "url": {
                                "type": "string"
                              },
                              "active": {
                                "type": "boolean"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/prices": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Current prices",
        "operationId": "getPrices",
        "responses": {
          "200": {
            "description": "Prices, order sizes and the activation fee.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "duration": {
                          "type": "string",
                          "enum": [
                            "15m"
                          ]
                        },
                        "energy": {
                          "type": "object",
                          "properties": {
                            "sunPerUnit": {
                              "type": "number",
                              "description": "SUN per unit of energy."
                            },
                            "min": {
                              "type": "integer",
                              "description": "Smallest order, in energy."
                            },
                            "max": {
                              "type": "integer",
                              "description": "Largest order, in energy."
                            },
                            "perTransfer": {
                              "type": "integer",
                              "description": "Energy one USDT transfer to a funded recipient burns."
                            },
                            "transferSun": {
                              "type": "integer",
                              "description": "What one transfer's worth of energy costs, fee included."
                            }
                          }
                        },
                        "bandwidth": {
                          "type": "object",
                          "properties": {
                            "sunPer1k": {
                              "type": "number",
                              "description": "SUN per 1,000 units of bandwidth."
                            },
                            "min": {
                              "type": "integer"
                            },
                            "max": {
                              "type": "integer"
                            }
                          }
                        },
                        "feeSun": {
                          "type": "integer",
                          "description": "Flat fee, one per order."
                        },
                        "activationSun": {
                          "type": "integer",
                          "description": "Charged once per address that does not exist on-chain yet."
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/address/{address}": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "What an address holds on-chain",
        "operationId": "checkAddress",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A TRON address."
          }
        ],
        "responses": {
          "200": {
            "description": "What the address has, and whether activation is due.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "address": {
                          "type": "string"
                        },
                        "activated": {
                          "type": "boolean"
                        },
                        "activationSun": {
                          "type": "integer",
                          "description": "Zero when the address already exists."
                        },
                        "trxBalanceSun": {
                          "type": "integer"
                        },
                        "energy": {
                          "type": "object",
                          "properties": {
                            "available": {
                              "type": "integer"
                            },
                            "limit": {
                              "type": "integer"
                            }
                          }
                        },
                        "bandwidth": {
                          "type": "object",
                          "properties": {
                            "available": {
                              "type": "integer"
                            },
                            "limit": {
                              "type": "integer"
                            }
                          }
                        },
                        "transfersCovered": {
                          "type": "integer",
                          "description": "USDT transfers the energy on hand pays for."
                        },
                        "energyForNextTransfer": {
                          "type": "integer",
                          "description": "Energy still missing for the next transfer; zero when covered."
                        },
                        "duration": {
                          "type": "string",
                          "enum": [
                            "15m"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The address could not be read from the network.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders": {
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "Recent orders",
        "description": "Newest first. A recent-activity feed rather than a full history, so there is no pagination.",
        "operationId": "listOrders",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The orders.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "status",
                          "resource",
                          "address",
                          "volume",
                          "duration",
                          "priceSun",
                          "feeSun",
                          "activationSun",
                          "totalSun"
                        ],
                        "properties": {
                          "id": {
                            "type": "integer",
                            "example": 41
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "sent",
                              "filled",
                              "failed"
                            ]
                          },
                          "resource": {
                            "type": "string",
                            "enum": [
                              "energy",
                              "bandwidth"
                            ]
                          },
                          "address": {
                            "type": "string",
                            "description": "The address the resource was delegated to."
                          },
                          "volume": {
                            "type": "integer",
                            "description": "Units of the resource."
                          },
                          "duration": {
                            "type": "string",
                            "enum": [
                              "15m"
                            ]
                          },
                          "priceSun": {
                            "type": "integer",
                            "description": "The resource itself, in SUN."
                          },
                          "feeSun": {
                            "type": "integer",
                            "description": "Flat fee, one per order."
                          },
                          "activationSun": {
                            "type": "integer",
                            "description": "Charged once per address, ever. Zero when the address already existed."
                          },
                          "totalSun": {
                            "type": "integer",
                            "description": "What was charged to the balance."
                          },
                          "txId": {
                            "type": "string",
                            "nullable": true
                          },
                          "error": {
                            "type": "string",
                            "nullable": true,
                            "description": "The provider's reason, on a failed order."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Buy energy or bandwidth",
        "description": "Charges the balance immediately, then delegates. Energy is rented for fifteen minutes, so place the order right before the transfer it is for. Send `Idempotency-Key` to make a retry safe. Needs a `purchase` key.",
        "operationId": "createOrder",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "A retry with the same key returns the first attempt's answer instead of buying twice. Kept 24 hours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "address",
                  "volume"
                ],
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "The address that SENDS the USDT — energy is spent by the sender."
                  },
                  "volume": {
                    "type": "integer",
                    "description": "65,000 covers one USDT transfer to a recipient that already holds USDT; 131,000 one to a recipient whose USDT balance is zero."
                  },
                  "resource": {
                    "type": "string",
                    "enum": [
                      "energy",
                      "bandwidth"
                    ],
                    "default": "energy"
                  },
                  "duration": {
                    "type": "string",
                    "enum": [
                      "15m"
                    ],
                    "default": "15m"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The order, charged and placed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": [
                        "id",
                        "status",
                        "resource",
                        "address",
                        "volume",
                        "duration",
                        "priceSun",
                        "feeSun",
                        "activationSun",
                        "totalSun"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 41
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "sent",
                            "filled",
                            "failed"
                          ]
                        },
                        "resource": {
                          "type": "string",
                          "enum": [
                            "energy",
                            "bandwidth"
                          ]
                        },
                        "address": {
                          "type": "string",
                          "description": "The address the resource was delegated to."
                        },
                        "volume": {
                          "type": "integer",
                          "description": "Units of the resource."
                        },
                        "duration": {
                          "type": "string",
                          "enum": [
                            "15m"
                          ]
                        },
                        "priceSun": {
                          "type": "integer",
                          "description": "The resource itself, in SUN."
                        },
                        "feeSun": {
                          "type": "integer",
                          "description": "Flat fee, one per order."
                        },
                        "activationSun": {
                          "type": "integer",
                          "description": "Charged once per address, ever. Zero when the address already existed."
                        },
                        "totalSun": {
                          "type": "integer",
                          "description": "What was charged to the balance."
                        },
                        "txId": {
                          "type": "string",
                          "nullable": true
                        },
                        "error": {
                          "type": "string",
                          "nullable": true,
                          "description": "The provider's reason, on a failed order."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The balance does not cover the order; `details.needed` is the amount in TRX.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The order is in doubt and must not be retried, or an idempotent request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Field errors, an idempotency key reused for a different body, or a refusal by the provider.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Orders are not being taken right now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders/{id}": {
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "One order",
        "operationId": "getOrder",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": [
                        "id",
                        "status",
                        "resource",
                        "address",
                        "volume",
                        "duration",
                        "priceSun",
                        "feeSun",
                        "activationSun",
                        "totalSun"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 41
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "sent",
                            "filled",
                            "failed"
                          ]
                        },
                        "resource": {
                          "type": "string",
                          "enum": [
                            "energy",
                            "bandwidth"
                          ]
                        },
                        "address": {
                          "type": "string",
                          "description": "The address the resource was delegated to."
                        },
                        "volume": {
                          "type": "integer",
                          "description": "Units of the resource."
                        },
                        "duration": {
                          "type": "string",
                          "enum": [
                            "15m"
                          ]
                        },
                        "priceSun": {
                          "type": "integer",
                          "description": "The resource itself, in SUN."
                        },
                        "feeSun": {
                          "type": "integer",
                          "description": "Flat fee, one per order."
                        },
                        "activationSun": {
                          "type": "integer",
                          "description": "Charged once per address, ever. Zero when the address already existed."
                        },
                        "totalSun": {
                          "type": "integer",
                          "description": "What was charged to the balance."
                        },
                        "txId": {
                          "type": "string",
                          "nullable": true
                        },
                        "error": {
                          "type": "string",
                          "nullable": true,
                          "description": "The provider's reason, on a failed order."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such order, or it belongs to someone else.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/automations": {
      "get": {
        "tags": [
          "Automations"
        ],
        "summary": "Standing orders",
        "operationId": "listAutomations",
        "responses": {
          "200": {
            "description": "The rules.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "kind",
                          "address",
                          "volume",
                          "status",
                          "autoResume"
                        ],
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "refill",
                              "renewal"
                            ]
                          },
                          "address": {
                            "type": "string"
                          },
                          "volume": {
                            "type": "integer",
                            "description": "Energy bought each time the rule fires."
                          },
                          "thresholdEnergy": {
                            "type": "integer",
                            "nullable": true,
                            "description": "refill only: buy when the address falls below this."
                          },
                          "runAtMinute": {
                            "type": "integer",
                            "nullable": true,
                            "description": "renewal only: minutes past midnight UTC, 0–1439."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "paused",
                              "suspended",
                              "canceled"
                            ]
                          },
                          "pausedBy": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                              "user",
                              "system",
                              null
                            ]
                          },
                          "autoResume": {
                            "type": "boolean",
                            "description": "Whether a rule the system suspended restarts after a top-up."
                          },
                          "lastFiredAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "silentSince": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Set when a daily rule has missed its slot."
                          },
                          "error": {
                            "type": "string",
                            "nullable": true
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Automations"
        ],
        "summary": "Create a standing order",
        "description": "Commits future spending: the rule buys again tomorrow with nobody watching. Needs a `full` key.",
        "operationId": "createAutomation",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "kind",
                  "address",
                  "volume"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "refill",
                      "renewal"
                    ]
                  },
                  "address": {
                    "type": "string"
                  },
                  "volume": {
                    "type": "integer"
                  },
                  "thresholdEnergy": {
                    "type": "integer",
                    "description": "refill only."
                  },
                  "runAtMinute": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1439,
                    "description": "renewal only."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The rule, already running.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": [
                        "id",
                        "kind",
                        "address",
                        "volume",
                        "status",
                        "autoResume"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "refill",
                            "renewal"
                          ]
                        },
                        "address": {
                          "type": "string"
                        },
                        "volume": {
                          "type": "integer",
                          "description": "Energy bought each time the rule fires."
                        },
                        "thresholdEnergy": {
                          "type": "integer",
                          "nullable": true,
                          "description": "refill only: buy when the address falls below this."
                        },
                        "runAtMinute": {
                          "type": "integer",
                          "nullable": true,
                          "description": "renewal only: minutes past midnight UTC, 0–1439."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "paused",
                            "suspended",
                            "canceled"
                          ]
                        },
                        "pausedBy": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "user",
                            "system",
                            null
                          ]
                        },
                        "autoResume": {
                          "type": "boolean",
                          "description": "Whether a rule the system suspended restarts after a top-up."
                        },
                        "lastFiredAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "silentSince": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Set when a daily rule has missed its slot."
                        },
                        "error": {
                          "type": "string",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Field errors, or the rule was refused — the message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/automations/{id}": {
      "get": {
        "tags": [
          "Automations"
        ],
        "summary": "One standing order",
        "operationId": "getAutomation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The rule.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": [
                        "id",
                        "kind",
                        "address",
                        "volume",
                        "status",
                        "autoResume"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "refill",
                            "renewal"
                          ]
                        },
                        "address": {
                          "type": "string"
                        },
                        "volume": {
                          "type": "integer",
                          "description": "Energy bought each time the rule fires."
                        },
                        "thresholdEnergy": {
                          "type": "integer",
                          "nullable": true,
                          "description": "refill only: buy when the address falls below this."
                        },
                        "runAtMinute": {
                          "type": "integer",
                          "nullable": true,
                          "description": "renewal only: minutes past midnight UTC, 0–1439."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "paused",
                            "suspended",
                            "canceled"
                          ]
                        },
                        "pausedBy": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "user",
                            "system",
                            null
                          ]
                        },
                        "autoResume": {
                          "type": "boolean",
                          "description": "Whether a rule the system suspended restarts after a top-up."
                        },
                        "lastFiredAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "silentSince": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Set when a daily rule has missed its slot."
                        },
                        "error": {
                          "type": "string",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such rule, or it belongs to someone else.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Automations"
        ],
        "summary": "Pause, resume, or change what happens after a top-up",
        "description": "Resuming is refused while the balance cannot cover one firing. Needs a `full` key.",
        "operationId": "updateAutomation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "paused"
                    ]
                  },
                  "autoResume": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The rule as it now stands.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": [
                        "id",
                        "kind",
                        "address",
                        "volume",
                        "status",
                        "autoResume"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "refill",
                            "renewal"
                          ]
                        },
                        "address": {
                          "type": "string"
                        },
                        "volume": {
                          "type": "integer",
                          "description": "Energy bought each time the rule fires."
                        },
                        "thresholdEnergy": {
                          "type": "integer",
                          "nullable": true,
                          "description": "refill only: buy when the address falls below this."
                        },
                        "runAtMinute": {
                          "type": "integer",
                          "nullable": true,
                          "description": "renewal only: minutes past midnight UTC, 0–1439."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "paused",
                            "suspended",
                            "canceled"
                          ]
                        },
                        "pausedBy": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "user",
                            "system",
                            null
                          ]
                        },
                        "autoResume": {
                          "type": "boolean",
                          "description": "Whether a rule the system suspended restarts after a top-up."
                        },
                        "lastFiredAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "silentSince": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Set when a daily rule has missed its slot."
                        },
                        "error": {
                          "type": "string",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such rule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The change was refused — the message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Automations"
        ],
        "summary": "Stop a standing order for good",
        "description": "It cannot be started again; create a new one instead. Needs a `full` key.",
        "operationId": "cancelAutomation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Stopped."
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such rule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/docs": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "These docs as Markdown",
        "description": "Send `If-None-Match` with the last `ETag` to get a 304 when nothing has changed.",
        "operationId": "getDocs",
        "responses": {
          "200": {
            "description": "The documentation.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "401": {
            "description": "Missing, invalid or revoked key, or a blocked owner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key's scope does not reach this endpoint, or it has spent its allowance for the day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. `Retry-After` says when to come back.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An energy key from the dashboard, `tbc_…`. Its scope decides which endpoints it opens."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "insufficient_balance"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Order": {
        "type": "object",
        "required": [
          "id",
          "status",
          "resource",
          "address",
          "volume",
          "duration",
          "priceSun",
          "feeSun",
          "activationSun",
          "totalSun"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 41
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "sent",
              "filled",
              "failed"
            ]
          },
          "resource": {
            "type": "string",
            "enum": [
              "energy",
              "bandwidth"
            ]
          },
          "address": {
            "type": "string",
            "description": "The address the resource was delegated to."
          },
          "volume": {
            "type": "integer",
            "description": "Units of the resource."
          },
          "duration": {
            "type": "string",
            "enum": [
              "15m"
            ]
          },
          "priceSun": {
            "type": "integer",
            "description": "The resource itself, in SUN."
          },
          "feeSun": {
            "type": "integer",
            "description": "Flat fee, one per order."
          },
          "activationSun": {
            "type": "integer",
            "description": "Charged once per address, ever. Zero when the address already existed."
          },
          "totalSun": {
            "type": "integer",
            "description": "What was charged to the balance."
          },
          "txId": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "The provider's reason, on a failed order."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Automation": {
        "type": "object",
        "required": [
          "id",
          "kind",
          "address",
          "volume",
          "status",
          "autoResume"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "kind": {
            "type": "string",
            "enum": [
              "refill",
              "renewal"
            ]
          },
          "address": {
            "type": "string"
          },
          "volume": {
            "type": "integer",
            "description": "Energy bought each time the rule fires."
          },
          "thresholdEnergy": {
            "type": "integer",
            "nullable": true,
            "description": "refill only: buy when the address falls below this."
          },
          "runAtMinute": {
            "type": "integer",
            "nullable": true,
            "description": "renewal only: minutes past midnight UTC, 0–1439."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "suspended",
              "canceled"
            ]
          },
          "pausedBy": {
            "type": "string",
            "nullable": true,
            "enum": [
              "user",
              "system",
              null
            ]
          },
          "autoResume": {
            "type": "boolean",
            "description": "Whether a rule the system suspended restarts after a top-up."
          },
          "lastFiredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "silentSince": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Set when a daily rule has missed its slot."
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}