For agents
Submit a capacity requirement on behalf of a team
The same request the run desk sends. Send what you know; a partial requirement is accepted, and what is missing comes back as open items carried into the reply.
Operated by Tempered Technologies LLC, 8 The Green STE B, Dover, DE 19901.
Endpoint
POST https://nodehour.forevenza.com/_c/request with content-type: application/json. need is required: the requirement in a sentence. Everything in specifications is optional.
Also served: /openapi.json (the schema), /mcp (a Model Context Protocol server; its tool list includes the request tool, which takes the same envelope) and /llms.txt.
A minimal request
Any chip, about 20,000 GPU-hours of fine-tuning in Q1 2027, US, InfiniBand preferred. No chip, no count, no exact start date, no contact: it is accepted, and the response lists what is still open, the missing reply address included ($.specifications.reply_email_included). The start is given in words (start_text, with the window inferred from them), not as a date and not in a timing object, so start_earliest stays in missing_specifications.
{
"action": "quote",
"need": "Enough capacity, any chip, for ~20,000 GPU-hours of fine-tuning in Q1 2027, US, InfiniBand preferred.",
"specifications": {
"gpu_hours": 20000,
"region": "United States",
"interconnect": "INFINIBAND",
"any_accelerator": true,
"start_text": "Q1 2027",
"inferred_start_window": {
"earliest": "2027-01-01",
"latest": "2027-03-31",
"from_words": "Q1 2027",
"basis": "inferred from the words; to confirm"
}
},
"quantity": {
"amount": 20000,
"unit": "GPU-hours"
},
"geography": {
"text": "United States",
"country": "US"
}
}
Send it from here
The same POST /_c/request, from this page. Edit the envelope and send: it records a real request, and the response is shown below exactly as returned, with what is still open read out of it.
What the response contains
{
"id": "the reference, quote it in any follow-up",
"facets": { "actionability": "the endpoint's label; see Dates", "missing_specifications": ["..."] },
"missing_specifications": ["$.specifications.accelerator", "$.specifications.accelerator_count", "$.specifications.start_earliest", "$.specifications.reply_email_included"],
"what_happens": "what Nodehour does next with this request"
}
id: the reference for this request.missing_specifications: required fields you did not send (chip, count, start, andreply_email_includedwhen no reply address was given). The request is kept with them open; Nodehour proposes or asks.facets.actionability: the endpoint's own label. DATED means the envelope carried atimingobject, not that a start date is set (see Dates).what_happens: the next step, as Nodehour states it.errors, with HTTP 400 and nothing recorded: a value of the wrong type (a string where a number belongs, words in a date field among them), a number outside a field's minimum or maximum, or a string over a field's maximum length. A request withoutneedis refused too. Nothing else is.
HTTP 400
{
"errors": ["specifications.start_earliest: ... (the field is named)"]
}
Without contact.email, no one can reply. specifications.reply_email_included is a required field. Set it to true whenever you send contact.email. While it is absent, missing_specifications lists $.specifications.reply_email_included: no reply address was given, so no one can reply and nothing goes to providers until a request with an address arrives. The endpoint does not read contact.email to clear it, and the address itself belongs only in contact.email. Contact details are deleted after 180 days.
A response is a receipt. It is not a quote, a reservation or an order.
Dates
- start_earliest, start_latest, finish_by and finish_latest are whole numbers YYYYMMDD: 4 January 2027 is 20270104. Send them that way, or leave them out.
- Anything that is not a whole number is refused: "Q1 2027", "sometime in Q1" and "2027-01-04" written as a string all return HTTP 400 with errors naming the field, and nothing is recorded. A whole number below 20260101 or above 20991231 is refused the same way.
- A whole number in that range is recorded as sent. It is not checked as a calendar day, so check 20270231-style mistakes yourself.
- A start known only in words goes in specifications.start_text, with an optional specifications.inferred_start_window {earliest, latest as YYYY-MM-DD, from_words, basis}. Leave start_earliest out: it then stays in missing_specifications.
- facets.actionability is DATED whenever the envelope has a top-level timing object, whatever it holds. Send timing only with dates, written there as YYYY-MM-DD strings (timing belongs to the envelope itself, not to the specification fields), and read whether the start is set from missing_specifications.
- Enum values are not checked: a value outside the listed set is recorded as sent.
The console above names anything in a date field that is not a whole number YYYYMMDD, and a timing object without a date, before sending. It offers two choices: fix it (a YYYY-MM-DD string becomes the number; words move, verbatim, to specifications.start_text and the field is left out, so the start stays open), or send exactly as written and see the endpoint refuse it. When nothing about the start is sent, it reads a quarter or month in need ("in Q1 2027") into specifications.inferred_start_window, marked inferred, and lists every change it made. A direct POST gets none of these adjustments; the endpoint's own checks are the ones listed here.
Specification fields
intent_text- The team's own description of the run, verbatim
workload_kind- PRETRAIN, FINE_TUNE, INFERENCE, GPU_HOURS or KNOWN_SPEC
model_params_b, training_tokens_b, target_tokens_per_s- The workload, when known
start_earliest, start_latest, finish_by, finish_latest- Dates as whole numbers YYYYMMDD (20270104). Anything else is refused with HTTP 400 naming the field. See "Dates" below
start_text- A start you can only describe ("Q1 2027", "sometime in Q1"), verbatim. It sets no date: start_earliest stays in missing_specifications
inferred_start_window- Optional {earliest, latest} as YYYY-MM-DD, with from_words and basis, when you infer a window from words. Recorded as an inference to confirm, not as a start
accelerator, accelerator_count- Chip and count; omit to have them proposed
accelerator_alternatives, min_accelerator_count- Substitutes and the smallest acceptable count
any_accelerator- true when any chip that fits is acceptable; each is sized and quoted. "Any chip" in the need sentence is read the same way
start_latest- The end of the start window; a range such as 4 to 15 January is start_earliest 20270104, start_latest 20270115
deadline_basis, finish_latest- With a start window: FIXED_DATE (finish_by holds whatever the start), ASSUMED_FIXED_DATE (not yet answered) or WEEKS_FROM_START (finish_latest is the last day)
reserved_gpu_hours_by_term, sizing_by_accelerator- Reserved GPU-hours per term, and the size on each chip to quote with its sizing_basis (RUN, MEASURED, SCALED, SHAPE, SPEC)
alternative_quoted- Whether the alternative configuration is quoted too
gpu_hours- Work in GPU-hours, if known
terms_to_quote- Array of 6_WEEKS, 1_MONTH, 2_MONTHS, 3_MONTHS, 6_MONTHS, 1_YEAR
interconnect- INFINIBAND, ROCE, ETHERNET or ANY
region, residency_required- Where, and whether it is a hard constraint
deployment- SLURM, KUBERNETES, BARE_METAL, VIRTUAL_MACHINES or MANAGED
commitment- READY_TO_SIGN, COMPARING_QUOTES or EXPLORING
budget_ceiling_usd_per_gpu_hour- Your own ceiling; not an offer
open_questions, conflicts- Plain sentences, carried into the reply
reply_email_included- Required. true when contact.email carries the reply address; absent, it is listed in missing_specifications as the signal that no one can reply
Top level, as for any request: quantity {amount, unit: "GPU-hours"}, timing {earliest, latest, text}, only with real dates (see Dates), geography {text, country}, budget {amount, currency, per}, requested_fields and contact {email, name, organization}.