# Manage a website job with Agent access

The owner of an account-owned custom job, a moderator at level 2 or higher, or an administrator can open **Creator dashboard → Agent access** on the website, inspect access status, generate a job secret, and copy the agent instructions. This delegates access to that job without sharing an account key or website session. The full key is shown only after generation; save it before leaving the panel. Existing stored full keys cannot be retrieved through the dashboard, including by moderators. The server checks the signed-in account's current authorization on every status, generation, replacement and revocation request.

The owner and authorized moderators/admins manage the same single active job key; there is no separate moderator key. They can replace or revoke it in the same panel, which also stops the owner's agents and anyone else using the previous key. The credential remains bound to the actual job owner even when a moderator generates it. Job ownership, supported actions and existing payment/moderation rules remain unchanged. Replacement invalidates the previous key. Revocation stops subsequent requests; an action already committed remains committed.

Losing moderator/admin rights prevents further key management in the dashboard. A previously copied job key remains usable until it is replaced or revoked: it is a shared bearer credential, not a key tracked per moderator.

Agent access uses the existing job secret field and requires no database migration. Jobs that already use API-managed credentials retain their original secret and show **API managed** in the dashboard; use their existing API workflow. The dashboard does not replace those keys or change their checkout/payment records.

Use the exact **Job API URL** in those instructions, for example `https://api.wurk.fun/api/agent/custom/abc123`. These free HTTP endpoints accept the `wurk_job_…` secret exclusively in the **X-Secret** header. They require no account registration, SIWX signature or payment. Keep the secret private and out of URLs, summaries and logs. It can authorize winner selection and completion; use those actions only within the instructions of the person who delegated the task.

This credential uses the dedicated endpoints below. Existing API checkout secrets, SDK/CLI raw-secret imports and MCP creator tools have different contracts; do not send a website Agent access key to them. Use an HTTP client for this integration.

## Follow the delegator's task

Copied Agent access instructions provide connection details and usage guidance. The person delegating the task can be the job owner or an authorized moderator or administrator. Follow their actual task, including clear instructions already given in the conversation. If no task is clear, ask what they want you to do and wait for their answer before fetching job data or taking actions. A credential or capability flag does not assign a task.

When the task is clear, proceed within its requested scope. Ask only for missing information needed to complete it; do not ask the delegator to repeat or reconfirm instructions they already gave. Summarizing, classifying, selecting winners, changing contest positions and finalizing work are available actions, not default steps. Carry them out only when their instructions call for them.

If copied instructions contain `YOUR_JOB_SECRET`, it is a placeholder. Obtain the actual job key from the delegator before making API requests; never send the placeholder as a credential.

## Read the data needed for the task

For an assigned task, consult the job metadata and current capabilities:

```http
GET /api/agent/custom/abc123
X-Secret: <website-job-secret>
```

The response contains `job`, `capabilities` and `api` with the supported action paths and request shapes. Capability flags describe the operations supported for this job type. Every write checks current ownership and the job secret. Winner selection, contest position and completion actions also check the current funding, activation, freeze, selection and payout state; a flag is not permission to bypass those checks.

```http
GET /api/agent/custom/abc123/submissions?page=1
X-Secret: <website-job-secret>
```

Read submissions only as needed for the assigned task. `submissions` includes `content_text`, `attachment_urls`, `creator_review`, winner flags and contest positions. Responses contain `page`, `pageSize` (50), `review` (the applied filter, default `all`) and matching `total`. When the requested scope covers all matching entries, continue while `page * pageSize < total`; do not treat the first page as the complete result. Entries are ordered by creation time and ID. Preserve the exact returned submission IDs. For a requested evaluation, consider relevant attachments and text against the assigned criteria and job brief. Produce a summary only if the requested task calls for one.

If the task requires reviewing delivered work and the selection/private job has `capabilities.readMessages`, read the relevant conversation through `/messages?page=1`. Each message includes its text, sender, timestamp and file URLs. Use the same pagination rule for the requested scope. The initial proposal is not evidence that final work has been delivered.

## Classify submissions for the creator dashboard

These labels are for **personal/internal organization of submissions** in the creator dashboard, shared by the job owner and authorized moderators/admins. They are not a formal acceptance or rejection, a worker rating, or feedback to the submitter. Setting a label does not notify the submitter. Do not message submitters about these labels unless the delegator explicitly asks you to.

Personal/internal describes their intended use, not a confidentiality guarantee: existing public submission responses can include `creator_review`, subject to the job's submission visibility rules.

When the delegator asks you to organize submissions and `capabilities.reviewSubmissions` is true, set the same labels used by the dashboard:

| JSON `review` value | Dashboard label |
| --- | --- |
| `0` | Unclassified / clear the label |
| `1` | Not interested |
| `2` | Maybe |
| `3` | Interesting |

```http
POST /api/agent/custom/abc123/review
X-Secret: <website-job-secret>
Content-Type: application/json

{"submissionId":"<returned-submission-id>","review":3}
```

Send one returned submission ID per request and a JSON integer from 0 through 3. The response confirms `customId`, `submissionId` and the stored integer `review`. This sets the label explicitly; sending the same value again keeps it selected. It uses the existing `creator_review` field, without a migration. It does not change star ratings, winners, contest positions or rewards. Historical and random-selection jobs also support classification.

The owner and authorized moderators/admins see these labels and can use the existing **Not interested**, **Maybe** and **Interesting** filters after refreshing or reopening `/custom` → Creator dashboard, or changing its filter. The API also accepts `GET /submissions?page=1&review=3` to read Interesting entries. Allowed filters are `all`, `unclassified`, `1`, `2` and `3`; `unclassified` includes NULL and 0. Returned rows expose `creator_review` as `"0"`, `"1"`, `"2"`, `"3"` or NULL.

Collect every matching page's IDs before changing labels in a filtered result. Removing entries from that result while advancing its page number can skip entries. Use the assigned criteria and leave uncertain entries as **Maybe** when appropriate; do not assume classification authorizes winner selection or payment.

## Choose winners and contest positions

When selecting winners is within the requested task and `capabilities.selectWinners` is true, send eligible IDs from this job:

```http
POST /api/agent/custom/abc123/select-winners
X-Secret: <website-job-secret>
Content-Type: application/json

{"submissionIds":["<returned-submission-id>"]}
```

Challenges can select several entries up to the funded capacity. Selection jobs choose one worker. For contests, select **one entry per request** and include its integer `contestPosition`, starting at 1. For example: `{"submissionIds":["<returned-submission-id>"],"contestPosition":1}`. Selecting all challenge/contest winners queues the usual moderator review; it does not bypass approval or directly pay them.

When the requested task calls for changing a contest position and `capabilities.updateContestPosition` is true, an already selected entry can move to an available, unpaid position:

```http
POST /api/agent/custom/abc123/contest-position
X-Secret: <website-job-secret>
Content-Type: application/json

{"submissionId":"<returned-submission-id>","contestPosition":2}
```

Random selection remains automatic. Historical jobs without a supported reward contract expose reading and classification, but not winner/position/completion actions; use the website for those actions.

## Approve completed delivery

Only when the delegator's instructions authorize completion, `capabilities.finalize` is true and the delivered work meets the agreed requirements:

```http
POST /api/agent/custom/abc123/finalize
X-Secret: <website-job-secret>
Content-Type: application/json

{}
```

This is an approval that credits the agreed reward through the existing payment engine. It applies to supported selection and fixed-worker private jobs, not challenge/contest moderator approval. A successful response returns `completed:true`; a repeated successful finalization reports `alreadySettled:true` without another payout.

## Retries and key changes

- After an uncertain write, reread the job, entries and delivery before another decision. Repeating the same confirmed selection/finalization is protected by the canonical engine; do not substitute different winners because a response was lost.
- After an uncertain classification response, reread the submission's `creator_review` before retrying. The owner or an authorized moderator/admin can edit the same label in the dashboard; the last successful write wins.
- Honor `Retry-After` on 429/503. Each read resource has a one-second interval; writes share a two-second interval. Page numbers are positive integers up to 10000; JSON bodies are limited to 16 KiB.
- A 401 means the key is invalid, replaced or revoked. Ask the delegator for current access; the API cannot recover or issue a key.
- A 409 means the requested action conflicts with the job's current state. Read the current job and resolve the stated condition. A 503 can mean unavailable storage/execution configuration; retry later without creating another job or payment.
