Tasks from a file, and sample files Built, not merged
Two things were missing for anyone working from a file:
- Nobody could see what an import file must hold. A new project's export is all but empty, and the format was written down only in the API document.
- Tasks could be made only one at a time. That was true on the pages and through the app API.
Both pages now offer Download a sample, and the Create a task page takes up to 50 tasks from one JSON file.
A file holds
1 to 50 tasks
Checked
All or nothing
Requests to the queue
One per file
Change budget
1 per 10 tasks
On the screen
- Cloud Tasks
- Queues
- Queue: email
- Create a task
Create a task
From a file
Up to 50 tasks at once, as a JSON file: { "tasks": [ ... ] }, each task with the fields of this form (only url is required; method is POST when left out; scheduleTime is ISO 8601 time with Z or an offset, at most 30 days ahead). Every task is checked first: when one is wrong, none is made, and the message names its place in the file (tasks.0 is the first).
The sample's two tasks call https://example.com/ as soon as they are created: change the url (and the rest) before you create them.
Tasks fileCreated 1 task; 1 could not be
| Task | Why |
|---|---|
sample-task-1 | A task named sample-task-1 is in this queue, or succeeded or was deleted within the last day |
What the panel says in other cases
A mistake in the file
None of the tasks is made. Each message names its place in the file.
Nothing was made
Every task was refused, so the label shows as a refusal.
Not a JSON file
Said on the page; nothing is sent.
Download a sample
Saved from the page itself; nothing is sent.
Export and import
Import
Preview shows what would change; nothing changes until you apply it. An import makes and changes queues, jobs, alert settings and the quota; it never deletes, and never makes a secret or a service account.
The file is JSON, as Download saves it. The sample holds one queue and one paused job, with every setting they take; a section left out of a file is not touched, and a setting left out takes its default.
Settings fileTo make: 1 queue and 1 job
| What | Name | To do | Settings that differ |
|---|---|---|---|
| Queue | sample-queue | Make | — |
| Job | sample-job | Make | — |
How the console handles a file of tasks
Each step runs only if the one before it passed. Beside each step is what happens when that step refuses.
-
The page reads the fileIt reads the file as JSON and sends it unchanged. However often the button is clicked while the request runs, it sends one request.The file is not JSON: the page says so and sends nothing.
-
Signed in, from the console's own pageThe session, the CSRF token and the page's origin. The request counts as one change against the person's hourly budget.401 or 403; 429 when the person's change budget is used up.
-
Allowed in this projectThe person needs the create permission. The queue is looked up in this project only.403 without the create permission; 404 for a queue this project doesn't have.
-
The whole file is checked first1 to 50 tasks and 256 KB at most. Each task is checked as a single create is, unknown fields are refused, and no task name may appear twice in the file.400, with a message for each problem at its place in the file. Nothing is made. A body over 256 KB gets 413.
-
Secrets and service accountsEvery secret and service account the file names must exist in the project, be of the right kind and not be disabled or expired. Its URLs must be ones that secret or account may go to. Two database reads, however many tasks there are.400 at the task's path, for example
tasks.1.auth.secret. Nothing is made. -
The person's change budgetA file counts one change per 10 of its tasks (5 for 50), so one person makes at most 1,200 tasks an hour from the pages.429, "Too many changes this hour". Nothing is made.
-
The project's daily quotaThe file's tasks are counted all at once, against the cap of 5,000 a day by default.429, saying how much room is left today, for example "room for 12 more today; the file has 30 tasks". Nothing is made.
-
The queue adds the tasksOne request to the queue adds each task in the file's order, and an unnamed task gets a name. The change is written to the audit log as a single line.A name the queue still remembers is refused for that task only, and its quota unit is given back. The other tasks are made.
-
The page shows the answerThe label, the refused tasks with why, and a link back to the queue. Once tasks are made, the page clears the chosen file, so a second click cannot make the unnamed ones again.Made. When nothing was made, the label appears as a refusal instead.
What the file holds
A JSON object with one field, tasks: a list of 1 to 50 tasks, each with the fields of the Create a task form. This is the sample:
{
"tasks": [
{
"name": "sample-task-1",
"method": "POST",
"url": "https://example.com/",
"headers": { "content-type": "application/json" },
"body": "{\"hello\":\"world\"}",
"auth": { "kind": "none" },
"attemptDeadline": "3m"
},
{
"method": "GET",
"url": "https://example.com/",
"auth": { "kind": "none" }
}
]
}
| Field | Needed | Rule |
|---|---|---|
url | Required | An http:// or https:// URL. Private, loopback and metadata addresses, and the console itself, are refused. |
method | Optional | POST when left out. |
name | Optional | 1 to 500 letters, digits, _ and -, and only once in the file. Left out, the queue names the task. A name the queue still remembers is refused. |
scheduleTime | Optional | An ISO 8601 time with Z or an offset, or Unix milliseconds, at most 30 days ahead. Left out or in the past, the task runs now. The sample leaves it out, so it never holds a date that has gone by. |
headers, body | Optional | As on the form. The body is at most 100 KB. |
auth | Optional | { "kind": "none" }, or one of the form's options, naming a secret or service account of this project. |
attemptDeadline | Optional | 15s to 15m; 3m when left out. |
The answers
| Answer | When | What was made |
|---|---|---|
| 200 Created 3 tasks | Every task was made. | All of them |
| 200 1 could not be | A name the queue still remembers, for example from a file sent twice. | The others; that task's quota unit is given back |
| 400 invalid | A problem in the file, or with a secret or account it names. Each problem is given at its path, such as tasks.2.name. | Nothing |
| 413 | The file is over 256 KB. | Nothing |
| 429 quota | The day has no room for every task in the file. | Nothing |
| 429 | The person's change budget for this hour is used up. | Nothing |
| 403, 404 | No create permission, or no such queue in this project. | Nothing |
The sample settings file (Export and import)
The Import panel's Download a sample saves cloud-console-settings-sample.json, which holds:
- the format and version
- one queue,
sample-queue, running, with every setting a queue takes - one cron job,
sample-job: paused, a POST to https://example.com/ every day at 09:00 in Asia/Kolkata, with no auth
Every other section is left out, so importing the sample unchanged makes those two and touches nothing else. Because the job is paused, nothing is called until someone resumes it.
-
Download a sample, and change itA setting left out takes its default; a section left out is not touched.The file is not JSON: the page says so and sends nothing.
-
PreviewA dry run: what would be made or changed, what is skipped and why, and which secrets and service accounts the file names that the project doesn't have.400 at the path in the file, for example
settings.queues.0.maxAttempts. -
ApplyShown only when the dry run allows it. Making the sample's queue and job needs the update and create permissions, and making the paused job needs pause as well.Made as one batch, with one line in the audit log.
On a phone, and against impatient clicks
- The From a file panel appears together with the form once it has loaded, so it never jumps down a phone's screen. It is as wide as the form.
- The file chooser's button uses the console's own style in light and dark mode.
- A refused task's long name is cut to its column and shown whole on hover.
- Only the summary line is read aloud by a screen reader; a refusal is an alert of its own.
- Double- or triple-clicking Create tasks, Preview or Apply sends one request. A test locks that in for each of them.
On main and deployed since pull request #25, after typecheck, lint and all 1,122 tests passed. It went in as three commits: CAP-159 (the plan and the API contract), CAP-160 (the sample settings file) and CAP-161 (tasks from a file). 22 Oct 2026.