Second-price auction calculator
With bids of 100, 95 and 80, the bidder at 100 wins but pays only 95, the second-highest bid, keeping a surplus of 5. Enter the sealed bids to see the winner, the price and the full ranking. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
A sealed-bid second-price auction—also called a Vickrey auction—awards the item to the highest bidder while charging only the second-highest bid. That pricing rule is the standard textbook mechanism for making truthful bidding a weakly dominant strategy when values are private and independent.
How a second-price sealed-bid auction chooses winner and price
In a sealed-bid second-price auction every participant submits one bid without seeing the others. After all bids are collected, the auctioneer ranks them from highest to lowest. Economists call this a Vickrey auction after William Vickrey’s classic result that, under independent private values, bidding your true value is a weakly dominant strategy because the price you pay does not depend on your own bid once you win.
This calculator implements that allocation-and-price rule exactly: it does not run English ascending clocks, Dutch descending clocks, or first-price sealed-bid payoffs. When two or more bids share the same highest amount, the earlier entry in your input list wins, so results stay deterministic for automated tests and LMS plugins. Negative amounts are rejected so the ranking never mixes invalid offers into a classroom-grade outcome.
Where this auction calculator helps
Principles and market-design courses use a second-price auction calculator so students can turn any short sealed-bid list into the canonical winner-and-price pair without confusing it with a first-price pay-your-bid rule. Exam generators and LMS plugins need a deterministic oracle that rejects empty or singleton bid lists and negative amounts instead of inventing a hollow zero price that a buggy grader might treat as success.
Procurement drills and classroom experiments that collect anonymous sealed offers can post the list once and show every participant the same winner, price paid, and surplus without standing up a full auction engine. Failed validation does not consume balance. Keep requests small, pin the ranking and surplus fields in tests, and you get reproducible Vickrey outcomes for homework, LMS plugins, and edge workers without building sealed-bid infrastructure of your own.
What you can do with it
Classroom Vickrey checks
Let students enter a sealed-bid list and verify that the highest bidder wins while paying only the second-highest amount.
LMS and exam auto-grading
Mark second-price auction items with a deterministic oracle that rejects singleton lists and negative bids.
Mechanism-design notebooks
Compute Vickrey winner, price paid, and bidder surplus beside first-price simulations without a full auction stack.
FAQ
What happens if two bidders tie for the highest amount?
The earlier entry in your input list wins. The next bid in that ranking sets the price, so a two-way high-tie yields price equal to the winning amount.
How does a second-price auction set the price?
The highest bidder wins but pays the second-highest bid instead of their own. With bids of 100, 95 and 80, the bidder at 100 wins and pays 95.
What is the bidder surplus?
It is the gap between the winning bid and the price paid. In that example the winner bid 100 and paid 95, so the surplus is 5, the margin the second-price rule leaves to the winner.
Why is bidding your true value the best strategy?
Because once you win, the price depends on the other bids, not on yours. With independent private values, bidding exactly what the item is worth to you is a weakly dominant strategy.
How many bids can I enter?
At least two, so that a second price exists, and up to five hundred. Each amount must be zero or more, and reserve prices are not applied.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/econ/second-price-auction \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"bids":[{"bidder":"Alice","amount":100},{"bidder":"Bob","amount":80},{"bidder":"Carol","amount":95}]}'const res = await fetch("https://api.kit.forhosting.com/econ/second-price-auction", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"bids": [
{
"bidder": "Alice",
"amount": 100
},
{
"bidder": "Bob",
"amount": 80
},
{
"bidder": "Carol",
"amount": 95
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/econ/second-price-auction",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"bids": [
{
"bidder": "Alice",
"amount": 100
},
{
"bidder": "Bob",
"amount": 80
},
{
"bidder": "Carol",
"amount": 95
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/econ/second-price-auction", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"bids":[{"bidder":"Alice","amount":100},{"bidder":"Bob","amount":80},{"bidder":"Carol","amount":95}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"bids":[{"bidder":"Alice","amount":100},{"bidder":"Bob","amount":80},{"bidder":"Carol","amount":95}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/econ/second-price-auction", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"bids": [
{
"bidder": "Alice",
"amount": 100
},
{
"bidder": "Bob",
"amount": 80
},
{
"bidder": "Carol",
"amount": 95
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "econ.second_price_auction",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
How a second-price sealed-bid auction chooses winner and price
At least two bids are required; a single bid cannot define a second-price payment without a reserve, and reserves are out of scope for this endpoint.
Input contract, response fields, and validation rules
Each object must include amount as a finite number greater than or equal to zero; bidder is an optional string label (name, seat, or agent id). Amounts are rounded to twelve decimal places for stable goldens across runtimes. POST a JSON body with one required field: bids, an array of at least two and at most five hundred bid objects. Common aliases are accepted for the whole array (list, offers, submissions) and for amount on each row (bid, value, price) as well as for the label (name, id, label). Missing bids, a non-array value, fewer than two entries, more than five hundred entries, non-object rows, missing or non-finite amounts, and negative amounts fail with invalid_input and are not billed. The endpoint does not settle multi-unit or combinatorial packages, does not apply reserve prices, and does not model risk preferences—only the classic single-item second-price ranking.
Where a second-price auction API earns its keep
Research notebooks and mechanism-design sandboxes often tabulate Vickrey outcomes next to first-price simulations; pinning the second-price column in a tiny parse API keeps spreadsheet drift out of the comparison.
Technical questions
How does a second-price (Vickrey) auction set the price?
The highest bidder wins the item, but the price paid equals the second-highest sealed bid (the runner-up), not the winner’s own bid.
How many bids do I need?
At least two. A second-price rule needs a runner-up amount; lists with fewer than two bids fail with invalid_input and are not billed.
What is bidder surplus in the response?
Bidder surplus is winning_bid minus price_paid. It is the gap between what the winner stated and what they actually pay under the second-price rule.
What does the second-price auction calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.