This document provides instructions on how to authenticate with and use the Stadium M2 Incubator Program API.
The API uses Sign-In with Substrate (SIWS) to protect certain endpoints (creating and updating projects). To access these routes, you must provide a valid, Base64-encoded SIWS signature in the x-siws-auth request header.
Only wallets listed in the ADMIN_WALLETS environment variable in the .env file are authorized to use these protected endpoints.
A utility page has been created in the frontend to simplify the process of generating this header.
-
Start the Frontend and Backend Servers:
- Backend:
npm startin theserverdirectory. - Frontend:
npm run devin theclientv2directory.
- Backend:
-
Navigate to the Auth Test Page:
- Open your browser and go to
http://localhost:8080/auth-test.
- Open your browser and go to
-
Connect Your Wallet:
- Click the "Connect Wallet" button and approve the connection in your Polkadot{.js} browser extension (e.g., Talisman).
-
Select an Admin Account:
- From the dropdown menu, choose an account whose address is present in the
ADMIN_WALLETSlist in your.envfile.
- From the dropdown menu, choose an account whose address is present in the
-
Generate the Signature:
- Click the "Generate Signature" button.
-
Copy the Header Value:
- A Base64 encoded string will appear on the page. Copy this entire string. This is the value for your
x-siws-authheader.
- A Base64 encoded string will appear on the page. Copy this entire string. This is the value for your
The server/rest-docs/ directory contains .http files that can be used with the VS Code REST Client extension for easy API testing.
projects.http: Covers general user journeys like discovering projects.projects-test.http: Provides an end-to-end test for a project's lifecycle (create, read, update).auth-test.http: Specifically for testing the authentication middleware.
To use them, open the file in VS Code and click the "Send Request" link that appears above each request. You can set the @authToken variable at the top of the files with the value you generated from the auth test page.
All endpoints are available under the /api prefix.
Retrieves a list of all projects in the M2 Incubator Program. Supports filtering and sorting.
- Method:
GET - Authentication: None
Query Parameters:
| Parameter | Type | Description | Example |
|---|---|---|---|
search |
String | Case-insensitive search for projects by their projectName. |
?search=My%20Project |
projectState |
String | Filters projects by a specific state (e.g., Hackathon Submission, Milestone Delivered, Abandoned). |
?projectState=Milestone%20Delivered |
bountiesProcessed |
Boolean | Filters projects based on whether their bounties have been processed. Can be true or false. |
?bountiesProcessed=true |
sortBy |
String | The field to sort by. Currently supports updatedAt. Defaults to updatedAt. |
?sortBy=updatedAt |
sortOrder |
String | The order for sorting. Can be asc (ascending) or desc (descending). Defaults to desc. |
?sortOrder=asc |
Example Request:
GET http://localhost:2000/api/m2-program?projectState=Milestone%20Delivered&sortOrder=ascCreates a new M2 program project.
- Method:
POST - Authentication: Required (Admin)
- Headers:
Content-Type: application/jsonx-siws-auth: <Your-Base64-Encoded-Signature>
Example Body:
{
"projectName": "My Awesome New Project",
"teamMembers": [{
"name": "Admin Lead",
"walletAddress": "5DAAnuX2qToh7223z2J5tV6a2UqXG1nS1g4G2g1eZA1Lz9aU"
}],
"description": "This is a test project created via the API.",
"hackathon": {
"id": "test-hack-2025",
"name": "Test Hack 2025",
"endDate": "2025-12-31T23:59:59Z"
},
"projectRepo": "https://github.com/test/repo",
"projectState": "Hackathon Submission"
}Retrieves a single project by its unique ID.
- Method:
GET - Authentication: None
Example Request:
GET http://localhost:2000/api/m2-program/my-awesome-new-project-a1b2c3Updates an existing project.
- Method:
PATCH - Authentication: Required (Admin or Project Team Member)
- Headers:
Content-Type: application/jsonx-siws-auth: <Your-Base64-Encoded-Signature>
A user is considered a team member if their wallet address is listed in the teamMembers array of the project.
Example Body:
You can send any subset of the project's fields to update.
{
"projectState": "Milestone Delivered",
"bountiesProcessed": true,
"description": "An updated description for the project."
}Example Request:
PATCH http://localhost:2000/api/m2-program/my-awesome-new-project-a1b2c3Replaces the team members array for a project.
- Method:
POST - Authentication: Required (Admin or Project Team Member)
- Headers:
Content-Type: application/jsonx-siws-auth: <Your-Base64-Encoded-Signature>
Example Body:
{
"teamMembers": [
{
"name": "Alice Johnson",
"walletAddress": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
"role": "Lead Developer",
"github": "alicejohnson"
},
{
"name": "Bob Smith",
"walletAddress": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"role": "Backend Developer"
}
]
}Example Request:
POST http://localhost:2000/api/m2-program/my-awesome-new-project-a1b2c3/teamUpdates the M2 Agreement (roadmap) for a project in the M2 Incubator Program.
- Method:
PATCH - Authentication: Required (Admin or Project Team Member)
- Headers:
Content-Type: application/jsonx-siws-auth: <Your-Base64-Encoded-Signature>
Notes:
- Team members can only edit the M2 Agreement during Weeks 1-4 of the incubator program
- Automatically adds
lastUpdatedBy: 'team'andlastUpdatedDatetimestamp - Preserves existing fields like
agreedDateandmentorName - Maximum 20 core features, 10 documentation items
- Each feature/doc item max 500 characters
- Success criteria max 2000 characters
Example Body:
{
"agreedFeatures": [
"Multi-chain portfolio aggregation with real-time updates",
"Historical performance charts with multiple time ranges",
"Transaction history explorer with advanced filtering",
"Portfolio analytics dashboard with ROI calculations"
],
"documentation": [
"Complete README with setup instructions",
"API documentation for all endpoints",
"Architecture diagram showing system components",
"User guide with screenshots"
],
"successCriteria": "Application must track assets across 20+ parachains with <5 second latency, support 50+ tokens, handle 1000+ transactions without performance issues, and provide 99%+ accurate portfolio calculations."
}Example Request:
PATCH http://localhost:2000/api/m2-program/polkadot-portfolio-tracker-a1b2c3/m2-agreement
Content-Type: application/json
x-siws-auth: <Your-Base64-Signature>
{
"agreedFeatures": ["Feature 1", "Feature 2"],
"documentation": ["Doc 1", "Doc 2"],
"successCriteria": "Success criteria text"
}Response:
{
"status": "success",
"data": {
"_id": "polkadot-portfolio-tracker-a1b2c3",
"projectName": "Polkadot Portfolio Tracker",
"m2Agreement": {
"agreedDate": "2025-10-28T10:00:00.000Z",
"agreedFeatures": ["Feature 1", "Feature 2"],
"documentation": ["Doc 1", "Doc 2"],
"successCriteria": "Success criteria text",
"lastUpdatedBy": "team",
"lastUpdatedDate": "2025-11-08T12:30:00.000Z"
}
}
}Updates the payout wallet address for M2 payments.
- Method:
PATCH - Authentication: Required (Admin or Project Team Member)
- Headers:
Content-Type: application/jsonx-siws-auth: <Your-Base64-Encoded-Signature>
Notes:
- Must be a valid SS58 address (47-48 characters)
- All changes are logged for security audit
- Old and new addresses are logged
- Critical for receiving M2 payments
Example Body:
{
"donationAddress": "5DAAnuX2qToh7223z2J5tV6a2UqXG1nS1g4G2g1eZA1Lz9aU"
}Example Request:
PATCH http://localhost:2000/api/m2-program/polkadot-portfolio-tracker-a1b2c3/payout-address
Content-Type: application/json
x-siws-auth: <Your-Base64-Signature>
{
"donationAddress": "5DAAnuX2qToh7223z2J5tV6a2UqXG1nS1g4G2g1eZA1Lz9aU"
}Response:
{
"status": "success",
"message": "Payout address updated successfully",
"data": {
"_id": "polkadot-portfolio-tracker-a1b2c3",
"projectName": "Polkadot Portfolio Tracker",
"donationAddress": "5DAAnuX2qToh7223z2J5tV6a2UqXG1nS1g4G2g1eZA1Lz9aU"
}
}Submits M2 deliverables for review.
- Method:
POST - Authentication: Required (Admin or Project Team Member)
- Headers:
Content-Type: application/jsonx-siws-auth: <Your-Base64-Encoded-Signature>
Notes:
- Can only submit during Weeks 5-6
- repoUrl must be a GitHub URL
- demoUrl must be YouTube or Loom video
- docsUrl must be a valid URL
- summary must be 10-1000 characters
- Changes status to 'under_review'
- Clears any previous change requests
Example Body:
{
"repoUrl": "https://github.com/team/polkadot-portfolio-tracker",
"demoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"docsUrl": "https://docs.portfolio-tracker.com",
"summary": "We successfully built a comprehensive portfolio tracker with multi-chain support, real-time updates, and beautiful analytics. All features from the M2 agreement have been implemented and tested with 100+ users."
}Example Request:
POST http://localhost:2000/api/m2-program/polkadot-portfolio-tracker-a1b2c3/submit-m2
Content-Type: application/json
x-siws-auth: <Your-Base64-Signature>
{
"repoUrl": "https://github.com/team/repo",
"demoUrl": "https://youtube.com/watch?v=demo",
"docsUrl": "https://docs.example.com",
"summary": "Project completed with all features implemented."
}Response:
{
"status": "success",
"message": "M2 deliverables submitted successfully. WebZero will review within 2-3 days.",
"data": {
"_id": "polkadot-portfolio-tracker-a1b2c3",
"projectName": "Polkadot Portfolio Tracker",
"m2Status": "under_review",
"finalSubmission": {
"repoUrl": "https://github.com/team/repo",
"demoUrl": "https://youtube.com/watch?v=demo",
"docsUrl": "https://docs.example.com",
"summary": "Project completed with all features implemented.",
"submittedDate": "2025-11-08T15:30:00.000Z",
"submittedBy": "5Di7WRCjywLjV53hVjdBekPo2mLtyZAxQYenvW1vKfMNCyo9"
}
}
}A simple health check endpoint to verify that the server is running.
- Method:
GET - Authentication: None
Example Response:
{
"status": "UP"
}