API Documentation

Integrate Mindova into your applications with our RESTful API

Getting Started

The Mindova API allows developers to programmatically interact with challenges, contributors, tasks, and teams. All endpoints below require authentication using a Laravel Sanctum bearer token.

Base URL

https://mindova.online/api

Authentication

All API requests must include an authentication token in the Authorization header.

Authorization: Bearer YOUR_API_TOKEN
Accept: application/json

Obtaining a Token

There is no standalone JSON login endpoint. A Sanctum token is issued automatically when a user authenticates through the web app — either with email/password or via LinkedIn — and is then available to that browser session.

  • POST /login (web form login, not under /api)
  • GET /api/auth/linkedin/redirect and /api/auth/linkedin/callback (LinkedIn OAuth)

On successful login, the server creates a Sanctum personal access token and stores it in the session. The app layout writes this token into localStorage.api_token for use by in-page JavaScript as a Bearer token. If you are building an external integration, generate a token for a service account the same way (log in once as that user) and store the resulting token securely on your side — it is not rotated automatically.

Revoking a Token

POST /api/auth/logout

Revokes all active tokens for the authenticated user.

Contributors

Complete Contributor Profile

POST /api/volunteers/complete-profile

Creates the contributor profile for the authenticated user. Returns 422 if a profile already exists.

{
  "availability_hours_per_week": 20,
  "bio": "Full-stack developer passionate about...",
  "field": "Software Engineering"
}

Get Current Contributor Profile

GET /api/volunteers/profile

Retrieves the authenticated contributor's profile information including skills and statistics.

Response

{
  "id": 1,
  "user_id": 1,
  "availability_hours_per_week": 20,
  "bio": "Full-stack developer passionate about...",
  "reputation_score": 75,
  "skills": [
    {
      "id": 1,
      "name": "JavaScript",
      "proficiency_level": "expert"
    }
  ]
}

Update Contributor Profile

PUT /api/volunteers/profile

Request Body

{
  "availability_hours_per_week": 25,
  "bio": "Updated bio text...",
  "field": "Data Science"
}

All fields are optional on update. CVs are not part of this endpoint — use the upload endpoint below.

Upload CV

POST /api/volunteers/upload-cv

Multipart upload. Replaces any existing CV and queues it for AI analysis.

  • cv — required file, one of pdf/doc/docx, max 10MB

Companies

Complete Company Profile

POST /api/companies/complete-profile

Creates the company profile for the authenticated user. Returns 422 if a profile already exists.

{
  "company_name": "Acme Inc.",
  "industry": "Technology",
  "website": "https://acme.example.com",
  "description": "What the company does...",
  "logo": "(multipart file, optional, jpeg/png/jpg/gif, max 2MB)"
}

Get Current Company Profile

GET /api/companies/profile

Returns the authenticated company's profile along with its challenges.

Update Company Profile

PUT /api/companies/profile

Accepts the same fields as profile completion; all fields are optional.

Challenges

List All Challenges

GET /api/challenges

Returns a paginated list of challenges.

My Challenges

GET /api/challenges/my-challenges

Returns challenges submitted by the authenticated company.

Get Single Challenge

GET /api/challenges/{id}

Returns detailed information about a specific challenge including its company, AI analyses, workstreams, tasks, and ideas.

Create Challenge

POST /api/challenges

Create a new challenge. Requires a company account. Dispatches AI brief analysis on submission.

Request Body

{
  "title": "Challenge Title",
  "description": "Detailed description (100-5000 characters)..."
}

Challenges have no deadline fields — there is no submission_deadline or completion_deadline.

Update Challenge

PUT /api/challenges/{id}

Owning company only, and only while the challenge is still submitted or analyzing.

{
  "title": "Updated title",
  "description": "Updated description (100-5000 characters)..."
}

Both fields are optional on update.

Archive Challenge

POST /api/challenges/{id}/archive

Owning company only. Sets the challenge status to archived.

Tasks

List Tasks

GET /api/tasks

Get Available Tasks

GET /api/tasks/available

Returns open tasks matched to the authenticated contributor's skills, excluding tasks they're already assigned to.

My Tasks

GET /api/tasks/my-tasks

Returns tasks the authenticated contributor has an assignment on.

Get Single Task

GET /api/tasks/{id}

Task Assignments

Assignments link a contributor to a task and move through a status lifecycle: invited → accepted/declined → in_progress → submitted → completed.

My Assignments

GET /api/assignments

Returns assignments for the authenticated contributor, or for tasks belonging to the authenticated company's challenges.

Pending Assignments

GET /api/assignments/pending

Accept / Reject Assignment

POST /api/assignments/{id}/accept

POST /api/assignments/{id}/reject

Only the invited contributor can respond, and only while status is invited. A contributor may only have one active task at a time, so accepting can fail with 422 if they already have one in progress.

// reject body (optional)
{
  "reason": "Not available this sprint"
}

Start / Complete Assignment

POST /api/assignments/{id}/start

POST /api/assignments/{id}/complete

Submit Solution

POST /api/assignments/{id}/submit-solution

{
  "description": "What was built and how (min 10 characters)",
  "deliverable_url": "https://github.com/...",
  "hours_worked": 12.5,
  "attachments[]": "(optional files, max 10MB each)"
}

Note: this endpoint currently always responds with a redirect rather than JSON, even for API clients. Treat a 2xx/3xx status as success and re-fetch the assignment to confirm.

Teams

Team formation and invitation responses are currently web-only features (session-based, not part of this token API). The API surface for teams is limited to in-team messaging.

List Team Messages

GET /api/teams/{id}/messages

Caller must be a member of the team.

Send Team Message

POST /api/teams/{id}/messages

{
  "message": "Text content, max 2000 characters"
}
Accepting or declining a team invitation is done via the web app at /teams/{id}/accept and /teams/{id}/decline — these require a logged-in browser session and are not reachable with a bearer token.

Notifications

List Notifications

GET /api/notifications

Unread Count

GET /api/notifications/unread-count

Mark Read

POST /api/notifications/{id}/mark-read

POST /api/notifications/mark-all-read

Delete Notification

DELETE /api/notifications/{id}

Ideas (Community Discussion Challenges)

  • GET /api/challenges/{challenge}/ideas — list ideas for a community-discussion challenge
  • POST /api/challenges/{challenge}/ideas{ "title", "description" } (description 100-2000 chars, contributor only, challenge must be active)
  • GET /api/ideas/my-ideas — ideas submitted by the authenticated contributor
  • GET /api/ideas/{id}
  • POST /api/ideas/{id}/vote{ "vote": -1 | 0 | 1 } (can't vote on your own idea; idea must already be AI-scored)

Error Codes

The API uses standard HTTP status codes:

Code Meaning
200 OK - Request successful
201 Created - Resource created successfully
401 Unauthorized - Invalid or missing token
403 Forbidden - Insufficient permissions, e.g. wrong account type or not the resource owner
404 Not Found - Resource does not exist
422 Unprocessable Entity - Validation failed, or the action is not valid for the resource's current status
500 Server Error - Something went wrong

Error Response Format

{
  "message": "Error message",
  "errors": {
    "field": ["Validation error message"]
  }
}

The "errors" object is only present on 422 validation failures. A few endpoints (notably submit-solution) are built primarily for the web UI and currently return a redirect instead of JSON — see the note on that endpoint above.

Rate Limits

There is currently no request-rate throttling configured on the API. Requests are not limited beyond standard server capacity, and no 429 responses or X-RateLimit-* headers are returned today.

Login attempts are the exception: the web login form is rate-limited to 5 attempts per email/IP combination before further attempts are blocked. Build integrations defensively and avoid tight polling loops — explicit API throttling may be introduced in the future.

Need Help?

For additional support with the API, please contact our developer support team.

Contact Developer Support

We use cookies to enhance your experience. By continuing, you agree to our cookie policy. Learn more