Commit to Task
API integration guide for committing to a project task as a contributor
Commit to Task
Committing to a task signals a contributor's intent to complete a specific piece of work within a project. On the contributor's first commit to a project, this transaction also "joins" the project by minting a contributor-state token. Subsequent commits by the same contributor skip minting — the state machine handles both cases automatically. This pattern is similar to course enrollment via student assignment commit.
Summary
| Property | Value |
|---|---|
| System | Project |
| Role | Contributor |
| Type Key | project_join |
| Build Endpoint | POST /api/v2/tx/project/contributor/task/commit |
| DB Sync | Yes |
| Service Fee | 0 ADA |
| Est. Wallet Cost | ~22 ADA (first enrollment) |
The estimated wallet cost on first enrollment breaks down as: transaction fee ~0.51 ADA + contributor-state deposit ~14.5 ADA + other UTxO deposits. Subsequent commits to the same project are significantly cheaper since the contributor-state token already exists and no new deposit is required.
Build Transaction
Endpoint
POST /api/v2/tx/project/contributor/task/commit
Request Body
{
"alias": "contributor1",
"project_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"contributor_state_id": "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5",
"task_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"task_info": "Starting implementation of the onboarding flow per spec v2.1",
"initiator_data": {
"usedAddresses": ["addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqwsx5wktcd8cc3sq835lu7drv2xwl2wywfgse35a3x"],
"changeAddress": "addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqwsx5wktcd8cc3sq835lu7drv2xwl2wywfgse35a3x"
}
}| Field | Type | Required | Description |
|---|---|---|---|
alias | string (Alias) | Yes | The contributor's access token alias. Must already have a minted access token. |
project_id | string (GYMintingPolicyId) | Yes | 56-character hex policy ID returned from project creation. |
contributor_state_id | string (GYMintingPolicyId) | Yes | The contributor-state policy ID for the project. Contributors must hold a token from this policy (or will receive one on first commit). |
task_hash | string | Yes | 64-character hex hash identifying the specific task to commit to. |
task_info | string | Yes | Evidence or context for the task commitment — a description of the contributor's plan or initial submission. |
initiator_data | WalletData | No | Object containing usedAddresses (string[]) and changeAddress (string). If omitted, the Gateway resolves wallet data from the authenticated session. |
Response
{
"unsigned_tx": "84a800..."
}The response contains the unsigned transaction CBOR, ready for the user's wallet to sign.
Register Transaction
After the user signs and submits the transaction, register it with the state machine:
POST /api/v2/tx/register
{
"tx_hash": "64-char hex hash from wallet.submitTx()",
"tx_type": "project_join",
"metadata": {
"task_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
}This is one of only 3 transaction types that require registration metadata. The task_hash in metadata links the on-chain commitment to the specific task in the database. On confirmation, the state machine records the commitment and links the contributor to the task.
Related API Endpoints
| Endpoint | Description |
|---|---|
GET /api/v2/projects/{project_id}/tasks | Fetch all tasks including contributor commitment status |
Example: Full Lifecycle
const API_URL = "https://api.andamio.io";
const taskHash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
// 1. Build
const buildRes = await fetch(`${API_URL}/api/v2/tx/project/contributor/task/commit`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
"Authorization": `Bearer ${userJwt}`,
},
body: JSON.stringify({
alias: "contributor1",
project_id: projectId,
contributor_state_id: contributorStateId,
task_hash: taskHash,
task_info: "Starting implementation of the onboarding flow per spec v2.1",
initiator_data: {
usedAddresses: [walletAddress],
changeAddress: walletAddress,
},
}),
});
const { unsigned_tx } = await buildRes.json();
// 2. Sign
const signedTx = await wallet.signTx(unsigned_tx);
// 3. Submit
const txHash = await wallet.submitTx(signedTx);
// 4. Register (requires metadata)
await fetch(`${API_URL}/api/v2/tx/register`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
"Authorization": `Bearer ${userJwt}`,
},
body: JSON.stringify({
tx_hash: txHash,
tx_type: "project_join",
metadata: { task_hash: taskHash },
}),
});
// 5. Monitor (SSE)
const events = new EventSource(
`${API_URL}/api/v2/tx/stream/${txHash}`
);
events.addEventListener("state_change", (e) => {
const data = JSON.parse(e.data);
console.log(`State: ${data.old_state} → ${data.new_state}`);
});
events.addEventListener("complete", (e) => {
const data = JSON.parse(e.data);
console.log(`Final: ${data.final_state}`);
events.close();
});See Also
- Transaction State Machine -- Lifecycle overview
- Contributor: Submit Task Work -- Submit evidence after committing
- Contributor: Claim Credential -- Claim reward after acceptance