Skip to content
Coritan Docs

How Object Storage is billed

The rates and free amounts, how we measure storage and count requests, how your use reaches an invoice, and how budgets and usage downloads work.

View as Markdown

Object Storage is pay as you go. You pay for what your buckets hold, by the GB-month, and for the requests they answer, by the million. Data your buckets send out is free. Each month your account uses some storage and some requests at no charge, and we bill the rest once a month, on the service's renewal invoice.

What Rate
Storage $0.0135 per GB-month
Class A operations $4.00 per million
Class B operations $0.32 per million
Egress Free
Deletes and CORS preflights Free

These are list prices in US dollars. The public Object Storage page and the Pricing card on the order page show the current rates, and a service's Billing tab shows the rates that service is billed at. The service itself costs $0 a month, so ordering one costs nothing.

Every account can use these amounts each calendar month at no charge. Your account plan sets the storage:

Account plan Storage Class A operations Class B operations
Free 10 GB-month 1 million 10 million
Pro 250 GB-month 1 million 10 million
Business 1,024 GB-month 1 million 10 million
Enterprise Set in your agreement 1 million 10 million
  • The free amounts are your account's. Every pay as you go Object Storage service on the account draws on them, so a second service adds no free use. Each hour's use takes from what is left, and once an amount runs out, the rest of the month's use of that meter is billed.
  • They start again at 00:00 UTC on the 1st of each month. What you do not use in a month does not carry over.
  • An Extra Object Storage 250 GB add-on that you already have adds 250 GB-month to the free storage (The storage add-on).
  • Each service's Billing tab shows how much of its use the free amounts covered. When more than one service draws on them, the Overview tab says so.
  • Once account plans open on your account, we email the account's owner when the month's storage reaches 80% of the free amount, and again when it reaches all of it, once a month each. These are Usage alerts emails, which you can turn off (Notifications). Storage above the free amount is billed, never refused.

A GB-month is one GB stored for a whole calendar month, where a GB is 1024³ bytes. Storage kept for part of a month counts for that part:

  • 100 GB kept for all of November is 100 GB-months.
  • 60 GB kept for 15 of November's 30 days is 30 GB-months.
  • 1,024 GB kept for one day of November is about 34.13 GB-months.

For example, on the Free plan your buckets hold 110 GB for all of November, and answer 2.5 million Class A operations and 25 million Class B operations. November's use comes to $12.15:

Meter Used Free Billed Amount
Storage 110 GB-months 10 GB-months 100 GB-months $1.35
Class A operations 2.5 million 1 million 1.5 million $6.00
Class B operations 25 million 10 million 15 million $4.80

We bill the exact use. Nothing is rounded up to the next GB-month or the next million, and each amount is rounded to the cent on the invoice.

Every hour, we list the objects in each of the service's buckets and record their total size and their number. For each hour of the month, a bucket counts the last measurement taken in that hour. When the hour has none, the bucket counts its last measurement from the 24 hours before. The hour then adds what the service's buckets held, divided by the number of hours in the month: 720 in a 30-day month and 744 in a 31-day month. A month's storage is therefore the average of what your buckets held, hour by hour.

  • A new bucket counts from its first measurement, up to an hour after you create it.
  • Objects you delete stop counting at the next measurement.
  • On a bucket that keeps versions, every version counts as stored data, the older ones as well as the current one. Delete markers hold no data (Versions and your bill).
  • A bucket you delete counts until the end of the hour you delete it in.
  • The sizes on the Overview tab and on the cards of the list of services come from the last measurement, so they trail uploads and deletions by up to an hour.

The Stored over time chart on the Overview tab shows the measurements of the last 7d, 30d or 90d, added up across the service's buckets. It includes a bucket you deleted for the hours before the delete, until we remove that bucket's history 7 days later. No measurements yet means no bucket was measured in the window you chose (The usage chart is empty).

Each request your buckets answer is a Class A operation, a Class B operation or free. Class A operations write or list, and Class B operations read.

Request S3 operations Class
PUT: an upload, a part of a multipart upload, a copy, or a change to a bucket or object setting PutObject, UploadPart, CopyObject A
POST: the start or the end of a multipart upload, or an upload from a browser form CreateMultipartUpload, CompleteMultipartUpload A
GET of a bucket: a list of its objects or of its multipart uploads ListObjectsV2, ListMultipartUploads A
GET /: the list of your buckets ListBuckets A
GET of an object with uploadId: the parts of a multipart upload ListParts A
GET of an object, or of a bucket setting such as ?location or ?cors GetObject, GetBucketLocation B
HEAD of an object or a bucket HeadObject, HeadBucket B
POST ?delete: a delete of several objects DeleteObjects Free
DELETE DeleteObject, AbortMultipartUpload Free
OPTIONS: a browser's CORS preflight — Free
  • A multipart upload is several Class A operations: one to start it, one for each part and one to complete it. A 1 GB file sent in 8 MB parts makes 130.
  • Uploads, downloads and new folders in the dashboard's object browser go over links we sign for you, so they count like requests from your own clients (Upload, download and delete objects). Presigned URLs from the API count the same way. The object browser's lists of objects and folders do not count.
  • Reads of a public bucket, at its public URL or a custom domain, count as Class B operations on the bucket's service when we read the object from storage. Reads we answer from our cached copy are free. A visitor's request for a key that does not exist counts too, and on a website it can count up to three times: the key, the folder's index document and the error document (How it is billed).
  • A request answered 404, such as a HEAD for an object that does not exist yet, counts.
  • Requests signed with temporary credentials count like requests signed with an access key. A request that names a bucket goes on the service that holds the bucket, and a list of your buckets goes on the service that created the credentials (Create temporary credentials).
  • A request that storage refuses for its signature or its permissions, answered 401 or 403, such as SignatureDoesNotMatch or AccessDenied.
  • A request refused before its signature is checked, because it is malformed (400), took too long to arrive (408), did not give its length (411), was too large (413) or had too long an address (414). Anyone who knows a bucket's name could send these, so they never reach your bill.
  • A request we throttled, answered 429.
  • A request that failed on our side, answered with a 5xx status.
  • Requests we make ourselves: the object browser's lists, the hourly measurement, and the removal of buckets after a service ends.
  • The lists and deletes that your lifecycle rules make (How rules run).
  • Version lists, restores and version deletes that you make in the dashboard or through the API, and the retentions and legal holds you set there. A download of an older version goes over a presigned URL, so it counts as a GET (Versions and your bill).

Copies we make for you are free: the requests of a migration and of replication are not counted as operations. The objects they create are billed as storage, in the service of the bucket they land in.

Egress is the data your buckets send out to the internet. It is free. The Billing tab shows how much the service sent this month, and the API returns it as egress_bytes. What we read from storage to answer requests to a public URL or custom domain counts as egress too.

We rate each hour's use two to three hours after the hour ends, so the figures for this month leave out the last few hours.

Estimated so far
What the service's use has cost this month, up to the last rated hour, after the free amounts. The list of services shows the same figure as This month on each pay as you go card, for a role that can see costs (What a role that cannot see costs sees).
Projected for the month
What the month comes to if the service keeps storing what it holds now, and keeps making requests at this month's pace.

The This month card on the Overview tab shows both, with a row for each meter against what is free each month. The Billing tab lists each meter's use, what the free amounts covered, what is billed and its amount (Manage the service on the Billing tab). The Requests chart on the Overview tab shows the Class A and Class B operations of each day over the last 7, 30 or 90 days.

A pay as you go service is a monthly service with a price of $0. Each month, its renewal invoice lists what it used above the free amounts since the last invoice, with a line for each meter:

Text
Object Storage storage: u7 photos, 1,234.5678 GB-months, 8 Oct to 7 Nov 2026
Object Storage Class A operations: u7 photos, 2.3456 million operations, 8 Oct to 7 Nov 2026
Object Storage Class B operations: u7 photos, 41.2 million operations, 8 Oct to 7 Nov 2026

Each line names the meter, the service, the quantity billed and the dates the use falls in. The quantity is what is left after the free amounts.

  • We raise the renewal invoice up to 3 days before the renewal date, and take it from your credit first, as for any renewal (How you are billed). Use from hours we have not rated by then goes on the next invoice.
  • A meter that comes to less than half a cent waits for the next invoice.
  • When the service owes nothing, the renewal comes to $0 and we mark it paid.
  • The free amounts follow calendar months, and the invoice follows the service's renewal date. An invoice from 8 Oct to 7 Nov covers the end of October and the start of November, each with its own free amounts.
  • When a service ends, we rate its last hours, and what it still owes goes on a final invoice of its own. That invoice is due 3 days after we make it, by default. A meter that comes to less than half a cent then is not billed.

An unpaid invoice suspends the service, as it does any other service: its access keys stop working, its objects stay where they are, and we bill nothing for the hours it is suspended. Pay the invoice to bring it back (Failed payments and suspended services).

A budget is a monthly amount in US dollars that you set on a service, to be told when its charges grow. When this month's charges reach 50%, 80% and 100% of the budget, we email the account's owner and its team members with the Billing or Admin role (Roles). Each alert goes once a month.

A budget sends alerts and does nothing else. The service goes on taking uploads and answering requests above it, and we bill what it uses.

  • A budget is from $1 to $1,000,000 a month.
  • It counts the charges of the calendar month, which Estimated so far shows. The Budget card on the Billing tab shows them against the budget, and the This month card on the Overview tab shows the share used, such as $25.00 a month · 12% so far. From 50% on, that card also opens with a notice such as This month's charges are 82% of the $25.00 budget.
  • We check each budget every hour, when we rate the hour's use. When the charges have passed more than one threshold since the last check, only the highest alert goes: charges that grow from 40% to 85% of the budget in one hour send the 80% alert alone.
  • When you change the amount, its alerts start over: we email at 50%, 80% and 100% of the new amount as the charges reach them. Each alert goes once a month for each amount.
  • Budget alerts are Billing emails, so they go even when you turn off Usage alerts (Notifications).
  • A service that has ended gets no alerts.
  • Set and remove it under Budget on the service's Billing tab (Set a budget), or through the API (Set or remove a budget).
  • One account can save or remove budgets 30 times an hour, across all its services. Everyone on its team and every API key share that limit.

Download usage on the Billing tab saves one month's use as a CSV file, with a row for each bucket and day, for your records or a finance tool. The file holds the use before the free amounts, which apply to the whole account.

Column Meaning
date The day
bucket The bucket's full name, such as u7-assets
region The code of the bucket's region, such as fra
gb_months The GB-months the bucket held that day
class_a Class A operations
class_b Class B operations
bytes_out Bytes the bucket sent out
  • The file covers only the hours we have rated, so this month's file leaves out the last two or three hours and grows each hour (The month so far).
  • A day with no use has no row, and neither does a bucket on a day it held nothing and answered no requests. A month with no use gives a file with only the header.
  • A row with an empty bucket and region holds requests that named no bucket, such as a list of your buckets.
  • A bucket you deleted keeps its rows, under its name, for 7 days after the delete. Then we remove its history: from that day on, the file has no storage for it, and its requests appear in a row with an empty bucket and region.

Object Storage used to be sold on fixed plans, each with a storage allowance in its price. We no longer sell them. A service on one keeps its price, its included storage and its rate for storage above it:

Plan Included storage Storage above it
Object Storage 250 GB 250 GB $0.02 per GB-month
Object Storage 1 TB 1,024 GB $0.015 per GB-month
Object Storage 5 TB 5,120 GB $0.012 per GB-month
  • We rate the storage above the included amount every hour, as a share of a GB-month, and bill it with the renewal.
  • Requests and egress are free on these plans, and the service does not draw on the account's free amounts.
  • The This month card on the Overview tab shows the included storage and the rate above it, and the Billing tab shows the plan's price. Both offer Switch to pay as you go.

Switch to pay as you go on the service's Overview or Billing tab moves a fixed plan to pay as you go (Switch to pay as you go has the steps). You cannot switch back, because the fixed plans are no longer sold. Pay as you go costs $0 a month, so the switch applies at once, and we add the unused part of the term you paid for to your credit balance:

  • We count the whole days left until the renewal date. The day in progress counts as used, and we keep back one more day by default.
  • Each day is worth the plan's price divided by the days in the term, and we round the credit down to the cent.
  • For example, Object Storage 1 TB at $16.00 a month, switched with 20 whole days left in a 30-day term, credits 19 days at $0.5333, which is $10.13.

The page shows the credit as Credit for the unused plan before you confirm (How the switch is billed).

The service keeps its buckets, objects, access keys and renewal date. From the switch on, its storage and requests are billed at the rates on this page, and it draws on the account's free amounts. Its use goes on the invoice for that renewal date, and the service renews every month after it. A plan you paid for a quarter or a year at a time can be months from its renewal date, so its first usage lines can be months away too. To see whether the switch saves you money, compare the plan's price with what your storage and requests would cost at those rates.

Extra Object Storage 250 GB is no longer sold. An add-on that you already have keeps renewing at its price, and adds 250 GB-month to your account's free storage each month. 250 GB-month at the storage rate costs less than the add-on, so to pay only for what you use, remove it (Remove an add-on). Your free storage then goes back to the plan's amount.

Storage from your account plan

Section titled Storage from your account plan

The dashboard used to create an Object Storage service from your account plan at no charge, and the API still can (Set up the services your plan includes). Such a service is pay as you go too: it renews at $0, draws on the same free amounts as your other services, and bills what it uses above them. When your account plan changes, the free amounts change with it.

  • The free amounts are the account's, and every pay as you go service shares them.
  • We measure storage once an hour, and rate each hour two to three hours after it ends.
  • The API returns up to 366 days of storage measurements and up to 90 days of requests. The charts show up to 90 days of each.
  • A budget is from $1 to $1,000,000 a month, and never stops the service. One account can save or remove budgets 30 times an hour.

Object Storage limits lists every limit.

The month so far through the API

Section titled The month so far through the API

GET /api/v1/billing/object-storage/{service_id} returns this month's use and charges for one service:

Shell
curl https://api.coritan.com/api/v1/billing/object-storage/1207 \
  -H "Authorization: Bearer $CORITAN_TOKEN"
JSON
{
  "service_id": 1207,
  "billing_model": "payg",
  "currency": "USD",
  "rates": {"storage_gb_month": "0.0135", "class_a_million": "4.00", "class_b_million": "0.32", "egress_gb": "0"},
  "month": "2026-10",
  "free": {"storage_gb_month": "10", "class_a": 1000000, "class_b": 10000000, "plan": "Free", "shared": false},
  "usage": [
    {"meter": "storage", "unit": "GB-month", "quantity": "12.4512", "included": "10", "billable": "2.4512", "amount": "0.03"},
    {"meter": "class_a", "unit": "operation", "quantity": "184211", "included": "184211", "billable": "0", "amount": "0.00"},
    {"meter": "class_b", "unit": "operation", "quantity": "2210345", "included": "2210345", "billable": "0", "amount": "0.00"}
  ],
  "egress_bytes": 51539607552,
  "month_to_date": "0.03",
  "projected": "0.11",
  "rated_through": "2026-10-08T07:00:00",
  "since": null,
  "next_invoice_date": "2026-11-08T00:00:00",
  "budget": {"monthly_amount": "25.00", "spent_pct": 0.0012, "alerted_pct": 0}
}
billing_model
payg for pay as you go, or fixed for a plan that is no longer sold.
rates
The service's rates in US dollars: storage_gb_month per GB-month, class_a_million and class_b_million per million operations, and egress_gb per GB sent out.
month
The calendar month the figures cover.
free
This month's free amounts: storage_gb_month in GB-months, and class_a and class_b in operations. plan names the account plan they come from. shared is true when more than one pay as you go service on the account draws on them.
usage
One entry for each meter, for the hours rated so far this month. quantity is what the service used, included the part the free amounts covered, billable the rest, and amount what billable costs.
egress_bytes
The bytes the service sent out this month, which are free.
month_to_date and projected
Estimated so far and Projected for the month, in US dollars.
rated_through
The end of the last hour we rated, in UTC. Use after it is not in usage yet.
since
null, except in the month a service moved from a plan that is no longer sold to pay as you go. Then it is when the service moved, in UTC, and usage, month_to_date and projected count from then. The hours before it reach the invoice at the old plan's terms.
next_invoice_date
The service's next renewal date, whose invoice carries the usage lines. For a service set to end, it is the day the service ends, and the final invoice follows once we have rated its last hours. It is null once the service has ended.
budget
null when the service has no budget. Otherwise monthly_amount in US dollars, spent_pct this month's charges as a fraction of it (0.31 is 31%), and alerted_pct the last alert sent this month: 0, 50, 80 or 100.

Amounts of money are strings with two decimal places, and quantities are strings with up to four. On a plan that is no longer sold, rates holds the plan's rate above its included storage as storage_gb_month and "0" for the rest, usage holds only the storage entry, and free holds the included storage with class_a and class_b set to null and the plan's name as plan.

GET /api/v1/client/object-storage/{service_id}/requests returns the operations counted each day, oldest first and ending today, in UTC. days sets the window, from 1 to 90 days, and is 30 when you leave it out:

Shell
curl "https://api.coritan.com/api/v1/client/object-storage/1207/requests?days=2" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
JSON
{
  "days": 2,
  "series": [
    {"date": "2026-10-07", "class_a": 98211, "class_b": 1180344, "free": 2140, "bytes_in": 3328599654, "bytes_out": 23085449216},
    {"date": "2026-10-08", "class_a": 101724, "class_b": 1241555, "free": 2237, "bytes_in": 3435973837, "bytes_out": 24159191040}
  ],
  "totals": {"class_a": 199935, "class_b": 2421899, "free": 4377, "bytes_in": 6764573491, "bytes_out": 47244640256}
}

class_a and class_b count each class of operation, and free the requests that cost nothing: deletes and CORS preflights. bytes_in and bytes_out are the bytes uploaded and sent out. A day with no requests has zeros, and totals adds up the window. The counts take in every bucket the service has had, and requests that name no bucket, such as a list of your buckets. We collect them once an hour, so the last hour or so is not in them yet.

GET /api/v1/client/object-storage/{service_id}/usage returns the hourly measurements behind the Stored over time chart. days sets the window, from 1 to 366 days, and is 30 when you leave it out.

Shell
curl "https://api.coritan.com/api/v1/client/object-storage/1207/usage?days=7" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
JSON
{
  "quota_bytes": null,
  "used_bytes": 13369344000,
  "object_count": 1284,
  "bucket_count": 2,
  "overage_gb": 0,
  "days": 7,
  "series": [
    {"measured_at": "2026-10-08T06:00:00", "bytes": 13363052544, "objects": 1283},
    {"measured_at": "2026-10-08T07:00:00", "bytes": 13369344000, "objects": 1284}
  ]
}

series has one point for each hourly measurement in the window, oldest first, in UTC. Each point adds up bytes and objects across the service's buckets. On pay as you go, quota_bytes is null and overage_gb is 0. On a plan that is no longer sold, quota_bytes is the included storage in bytes, and overage_gb is what the buckets held above it at the last measurement, in GB of 1024³ bytes.

PUT /api/v1/billing/object-storage/{service_id}/budget sets the budget, or changes it. monthly_amount is in US dollars, from 1 to 1000000, as a number or a string such as "25.00":

Shell
curl -X PUT https://api.coritan.com/api/v1/billing/object-storage/1207/budget \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"monthly_amount": 25}'

It answers with the budget, as budget in the month so far holds it. A new amount has alerted_pct 0, because its alerts start over:

JSON
{"monthly_amount": "25.00", "spent_pct": 0.0012, "alerted_pct": 0}

An amount that is not a number answers 422 with monthly_amount must be a number of US dollars, and one outside the range with A budget is between $1 and $1,000,000 a month. DELETE /api/v1/billing/object-storage/{service_id}/budget removes it, and answers {"ok": true} whether or not the service had one:

Shell
curl -X DELETE https://api.coritan.com/api/v1/billing/object-storage/1207/budget \
  -H "Authorization: Bearer $CORITAN_TOKEN"

The two routes share a limit of 30 requests an hour for each account, with the dashboard's Save budget and Remove budget. Every request counts, including one answered 422 or 404, except one the limit refuses. Over the limit, both answer 429 with the header Retry-After: 3600:

JSON
{
  "detail": {
    "error": "rate_limited",
    "message": "Too many requests for this action. Try again later.",
    "retry_after_seconds": 3600
  }
}

Wait the seconds that Retry-After gives, then send the request again (Handle a 429).

GET /api/v1/billing/object-storage/{service_id}/usage.csv returns the CSV file that Download usage saves. month names the month as YYYY-MM:

Shell
curl -o usage-2026-10.csv "https://api.coritan.com/api/v1/billing/object-storage/1207/usage.csv?month=2026-10" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
Text
date,bucket,region,gb_months,class_a,class_b,bytes_out
2026-10-01,u7-assets,fra,0.3871,18211,402115,1288490188
2026-10-01,u7-backups,fra,1.2903,1420,96,0

Switch a fixed plan to pay as you go

Section titled Switch a fixed plan to pay as you go

Find the pay as you go plan in the catalogue with GET /products/: it is the Object Storage product whose module_name is object_storage and whose metadata.billing_model is payg, and the id of its one pricing entry is the plan. Preview the switch with that id as new_pricing_id:

Shell
curl "https://api.coritan.com/api/v1/services/1207/upgrade-preview?new_pricing_id=171" \
  -H "Authorization: Bearer $CORITAN_TOKEN"

For the Object Storage 1 TB service in Switch to pay as you go, with 20 whole days left in a 30-day term, it answers:

JSON
{
  "credit_amount": 10.67,
  "charge_amount": 0.0,
  "net_amount": -10.67,
  "credit_estimate": 10.13,
  "creditable_days": 19,
  "days_remaining": 20,
  "days_in_cycle": 30,
  "change_type": "downgrade"
}

credit_estimate is what the switch adds to your credit balance, for creditable_days. credit_amount is the value of all the days left, before we keep one back. Apply the switch with the same id:

Shell
curl -X POST https://api.coritan.com/api/v1/services/1207/change-plan \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"new_pricing_id": 171}'

It answers with "status": "applied" and the credit it added as credit_issued, here 10.13. Change a service's plan explains the other fields and the errors. A pay as you go service has no plan to switch to: another product's plan answers 400 with New pricing must belong to the same product, and a service your account plan created answers 400 with Included services follow your account plan. Change your plan instead.

The routes under /api/v1/billing follow your team's billing roles (Roles). A member with the Billing or Admin role can set and remove a budget. A Read only member can read the month so far and download usage, and a Technical member can do neither. The requests and storage measurements under /api/v1/client/object-storage are open to every role. A switch to pay as you go is a plan change under /api/v1/services, so it takes the Technical or Admin role.

Every route answers 404 with Object storage service not found for a service ID that is not an Object Storage service on your account.

API operations on this page

MethodPathWhat it does
GET/api/v1/client/object-storage/{service_id}One service with its endpoints, its limits and how it is billed
GET/api/v1/client/object-storage/{service_id}/usageStored bytes and objects over time, as the hourly meter recorded them
GET/api/v1/client/object-storage/{service_id}/requestsRequests to the service per day, for the last days days
GET/api/v1/billing/object-storage/{service_id}Object storage billing
PUT/api/v1/billing/object-storage/{service_id}/budgetSet the service's monthly budget, or change it
DELETE/api/v1/billing/object-storage/{service_id}/budgetRemove the service's monthly budget, and with it the alerts
GET/api/v1/billing/object-storage/{service_id}/usage.csvObject storage usage CSV