Skip to main content

Missions API

The Missions API allows you to create, manage, and discover missions on Horizon Protocol.

Endpoints​

MethodEndpointDescription
GET/missionsList missions
GET/missions/:idGet mission details
POST/missionsCreate mission
PATCH/missions/:idUpdate mission
POST/missions/:id/acceptAccept mission
POST/missions/:id/submitSubmit proof
POST/missions/:id/approveApprove completion
POST/missions/:id/cancelCancel mission
POST/missions/:id/disputeRaise dispute

List Missions​

GET /missions

Query Parameters​

ParameterTypeDescription
statestringFilter by state: Open, Accepted, Submitted, Completed, Cancelled, Disputed
categorystringFilter by category
guildIdstringFilter by guild
posterIdstringFilter by poster
performerIdstringFilter by performer
minRewardstringMinimum reward amount
maxRewardstringMaximum reward amount
skipnumberPagination offset
takenumberResults per page (max 100)
sortBystringSort field: createdAt, rewardAmount, expiresAt
sortOrderstringasc or desc

Response​

{
"data": [
{
"id": "mission-uuid",
"onChainId": "123",
"title": "Deliver package",
"description": "Pick up from store...",
"state": "Open",
"category": "delivery",
"rewardAmount": "10.000000",
"poster": {
"id": "user-uuid",
"evmAddress": "0x...",
"resolvedName": "alice.eth"
},
"performer": null,
"guild": {
"id": "guild-uuid",
"name": "Delivery Guild"
},
"location": {
"latitude": 40.7128,
"longitude": -74.0060,
"radius": 100
},
"expiresAt": "2026-01-18T12:00:00Z",
"createdAt": "2026-01-17T12:00:00Z"
}
],
"meta": {
"skip": 0,
"take": 20,
"total": 150
}
}

Get Mission​

GET /missions/:id

Response​

{
"data": {
"id": "mission-uuid",
"onChainId": "123",
"escrowAddress": "0x...",
"title": "Deliver package",
"description": "Full description...",
"state": "Open",
"category": "delivery",
"rewardAmount": "10.000000",
"ddrAmount": "0.500000",
"poster": { ... },
"performer": null,
"guild": { ... },
"location": { ... },
"proofHash": null,
"metadata": { ... },
"expiresAt": "2026-01-18T12:00:00Z",
"createdAt": "2026-01-17T12:00:00Z",
"acceptedAt": null,
"completedAt": null
}
}

Create Mission​

POST /missions

Request Body​

{
"title": "Deliver package",
"description": "Pick up from Joe's Coffee (123 Main St) and deliver to Central Park entrance",
"rewardAmount": "10.00",
"category": "delivery",
"expiresIn": 86400,
"location": {
"latitude": 40.7128,
"longitude": -74.0060,
"radius": 100
},
"guildId": "guild-uuid",
"metadata": {
"pickupAddress": "123 Main St",
"dropoffAddress": "Central Park South"
}
}

Parameters​

FieldTypeRequiredDescription
titlestringYesMission title (max 100 chars)
descriptionstringYesDetailed description
rewardAmountstringYesUSDC amount (e.g., "10.00")
categorystringYesMission category
expiresInnumberYesSeconds until expiration
locationobjectNoLocation requirements
guildIdstringNoAssociated guild
metadataobjectNoAdditional data

Response​

{
"data": {
"id": "mission-uuid",
"onChainId": "123",
"escrowAddress": "0x...",
"transactionHash": "0x...",
...
}
}

Accept Mission​

POST /missions/:id/accept

Response​

{
"data": {
"success": true,
"transactionHash": "0x...",
"mission": { ... }
}
}

Submit Proof​

POST /missions/:id/submit

Request Body​

{
"proofType": "photo",
"proofData": "ipfs://...",
"notes": "Delivered to front desk"
}

Response​

{
"data": {
"success": true,
"transactionHash": "0x...",
"proofHash": "ipfs://..."
}
}

Approve Completion​

POST /missions/:id/approve

Poster approves that the mission was completed successfully.

Request Body​

{
"rating": 5,
"feedback": "Great job!"
}

Response​

{
"data": {
"success": true,
"transactionHash": "0x...",
"settlement": {
"performerAmount": "9.000000",
"protocolAmount": "0.250000",
"guildAmount": "0.300000",
"labsAmount": "0.250000",
"resolverAmount": "0.200000"
}
}
}

Cancel Mission​

POST /missions/:id/cancel

Only the poster can cancel, and only before acceptance.

Response​

{
"data": {
"success": true,
"transactionHash": "0x...",
"refundAmount": "10.000000"
}
}

Raise Dispute​

POST /missions/:id/dispute

Either party can raise a dispute after submission.

Request Body​

{
"reason": "Work not completed as specified",
"evidence": "ipfs://..."
}

Response​

{
"data": {
"success": true,
"disputeId": "dispute-uuid",
"onChainDisputeId": "456"
}
}

Mission States​

StateDescription
OpenAvailable for acceptance
AcceptedClaimed by performer
SubmittedProof submitted, awaiting approval
CompletedApproved and settled
CancelledCancelled by poster
ExpiredExpired without acceptance
DisputedIn dispute resolution

Error Responses​

CodeDescription
MISSION_NOT_FOUNDMission doesn't exist
MISSION_NOT_OPENCannot accept - wrong state
ALREADY_ACCEPTEDMission already has performer
NOT_POSTEROnly poster can perform action
NOT_PERFORMEROnly performer can perform action
INSUFFICIENT_BALANCENot enough USDC
INELIGIBLEUser doesn't meet requirements

Webhooks (Coming Soon)​

Subscribe to mission events:

{
"event": "mission.accepted",
"data": {
"missionId": "mission-uuid",
"performerId": "user-uuid",
"timestamp": "2026-01-17T12:00:00Z"
}
}

SDK Example​

import { parseUSDC } from '@horizon-protocol/sdk';

// Create mission via API
const response = await fetch('https://api.horizon.dev/missions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'Deliver package',
description: 'Pick up and deliver',
rewardAmount: '10.00',
category: 'delivery',
expiresIn: 86400,
}),
});const { data } = await response.json();
console.log('Mission created:', data.id);