Commit to Assignment
API integration guide for students to enroll in a course and commit to an assignment
Commit to Assignment
A student commits to a specific module assignment within a course. If the student is not yet enrolled, this transaction handles enrollment and the first assignment commitment in a single step. If already enrolled, it commits to an additional assignment. The state machine handles both cases transparently.
Summary
| Property | Value |
|---|---|
| System | Course |
| Role | Student |
| Type Key | course_enroll |
| Build Endpoint | POST /api/v2/tx/course/student/assignment/commit |
| DB Sync | No |
| Service Fee | 0 ADA |
| Est. Wallet Cost | ~2.14 ADA |
The estimated wallet cost breaks down as: transaction fee ~0.40 ADA + course state deposit ~1.45 ADA + global state delta ~0.29 ADA. The course state deposit is recoverable when the student claims their course credential.
Build Transaction
Endpoint
POST /api/v2/tx/course/student/assignment/commit
Request Body
{
"alias": "student1",
"course_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"slt_hash": "9f3a1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a",
"assignment_info": "e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6",
"initiator_data": {
"usedAddresses": ["addr1qx2fxv..."],
"changeAddress": "addr1qx2fxv..."
}
}| Field | Type | Required | Description |
|---|---|---|---|
alias | string (Alias) | Yes | The student's access token alias. Must have a minted access token. |
course_id | string (GYMintingPolicyId) | Yes | The 56-character hex course policy ID. |
slt_hash | string (SltHash) | Yes | The 64-character hex hash of the module the student is committing to. |
assignment_info | string | Yes | Evidence hash for the assignment — a hash of the student's submitted work or a reference to it. |
initiator_data | WalletData | No | Object containing usedAddresses (string[]) and changeAddress (string). Note: this endpoint uses initiator_data rather than walletData. |
Response
{
"unsigned_tx": "84a800..."
}Note that this endpoint returns unsigned_tx rather than unsignedTxCBOR. The value is the same — an unsigned transaction CBOR ready for the 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": "course_enroll"
}No metadata is required. Enrollment status is tracked entirely on-chain. The type key is course_enroll because this endpoint replaces the original enrollment endpoint — a commit is effectively an enrollment-plus-assignment in one step.
Related API Endpoints
| Endpoint | Description |
|---|---|
GET /api/v2/courses/{course_id} | Fetch course details including the module list and their SLT hashes |
Example: Full Lifecycle
const API_URL = "https://api.andamio.io";
// 1. Build
const buildRes = await fetch(`${API_URL}/api/v2/tx/course/student/assignment/commit`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
"Authorization": `Bearer ${userJwt}`,
},
body: JSON.stringify({
alias: "student1",
course_id: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
slt_hash: "9f3a1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a",
assignment_info: "e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6",
initiator_data: {
usedAddresses: [walletAddress],
changeAddress: walletAddress,
},
}),
});
const { unsigned_tx } = await buildRes.json();
const signedTx = await wallet.signTx(unsigned_tx);
// 3. Submit
const txHash = await wallet.submitTx(signedTx);
// 4. Register
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: "course_enroll",
}),
});
// 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
- Student: Update Assignment -- Revise submitted evidence
- Teacher: Manage Modules -- How modules are created