DevRelay MLH Submissions

Project submission is a chain of MLH writes, each acting as the MLH account connected to DevRelay, and MLH enforces the order and the rules, the same ones its website enforces. Your job is to call the steps in order, pass MLH’s answers through faithfully, and never claim a result MLH did not return.

MLH events submit one of two ways, and get_mlh_event tells them apart only by what MLH answers, so follow the event’s own instructions when they say:

With the user, use the words MLH’s website uses: the project, its submission to the event (not “event submission”), and the prize categories it entered (not “challenge entries”; at a challenge-first event, the challenges it entered). The tool names keep the API’s terms; the user never needs them.

The chain

  1. list_my_mlh_events — find the event and the user’s participation. At an event whose registration and check-in run on MLH, MLH requires the user to be checked in, as its website does, and refuses steps 5 and 6 and project edits otherwise (“You are not registered or checked in at {event}.”); any other event needs only the connected account. When the user is not registered, find the event with search_mlh_events (or take the id, slug, or mlh.com URL they give), confirm it with them, and offer register_for_mlh_event; when they are registered but not checked in, offer check_in_to_mlh_event once the event’s check_in.state allows it. Then continue.
  2. get_mlh_event with the event id — the challenges (prize categories), each with an id, name, prize description, and a description that is the sponsor’s own statement of what they want built and judged. Read those descriptions; the names (“Best Use of Vultr”) say nothing about the criteria, and a track claimed against the name alone is a track the judges will score against the text. Note which are active.
  3. Check the event takes submissions through MLH at all, before creating anything. An event whose submission_url points at Devpost or another third-party platform does not: MLH will refuse step 5, and a project created in step 4 will exist attached to no event. When you see that, say so, give the user that URL, and stop here. Do not create the MLH project to “have it ready”.
  4. list_my_projects — a project can be submitted to one MLH event only. Reuse an existing project only when it is not yet submitted to any event, or is already submitted to this one; list_my_projects does not say which, so ask the user when it is unclear. Otherwise create_project a new one for this event, even for the same repository, with the repository source_url (a project-first event requires a GitHub, GitLab or Bitbucket repository; a project can start without one), built_with, short_description, and ai_tools, plus name, description, demo URLs, extra_links, and screenshot_paths when known. Always send built_with: many events reject a submission with no technologies (“Select at least one technology”). When the stack is unknown, infer it from the repository (manifests, imports) or ask the user. When reusing a project with any of these empty, fill them with update_project before submitting. See “The submission fields” below.
  5. Project-first: submit_project_to_event with the project id and event id, in the same turn as create_project — nothing goes between them. One project per participant per event and one event per project, while the event’s submission window is open. Challenge-first: skip this step; step 6 submits the project.
  6. enter_challenge with the project id, event id, each chosen challenge id, and its sponsor_usage. At a project-first event the event submission must exist first; MLH refuses otherwise. Enter at least one: a submission with no entries does not show in the gallery. MLH holds the project to each challenge’s own required fields (a screenshot, a demo URL) and answers 422 naming what is missing. MLH may approve an entry at once, which locks the project, so finish update_project edits before this step. A challenge that runs with no event takes enter_challenge without an event_id.

update_project changes only the fields passed. Use it to fix a project after a 422 or when the user adds a demo link or a screenshot. Never clear built_with on a submitted project: the technology requirement applies to edits too.

MLH locks the project and all of its entries once an entry at its event is approved or wins, or that event’s submission window closes. Every edit, answer change, withdrawal, and reactivation is then refused.

update_challenge_entry, withdraw_challenge_entry, and reactivate_challenge_entry act on an entry id from enter_challenge until then. update_challenge_entry changes the entry’s sponsor_usage, and a blank answer clears it. Only a draft or submitted entry can be withdrawn, and withdrawing needs a reason; DevRelay sends a default when the user gives none. Reactivating re-enters an entry the team withdrew, and only that: an entry the organizers rejected cannot be brought back (“Only withdrawn entries can be reactivated; this one is rejected.”). Tell the user to contact the event’s organizers about it.

The team

A teammate joins through an invite: create_project_invite returns the project’s live invite, its invite_url for a teammate on the website and its token for join_project when the teammate uses DevRelay. MLH refuses a join once the team is locked, when the project’s event requires a check-in the joiner lacks, or when the joiner is already on another project at that event. list_my_projects shows the team as members ({id, user_id, name}); remove_project_member takes a member’s id to remove a teammate, or the user’s own to leave. Anyone may leave, the member who submitted the project may remove others, and the submitter and the last member cannot be removed. Confirm with the user before removing anyone.

The submission fields

Reading MLH’s answers

Before you write

Submissions and entries are visible to organizers and judges. Confirm the event with the user before calling register_for_mlh_event, the project and event before submit_project_to_event, and the project, event, and challenges before enter_challenge. After each write, tell the user what MLH did in plain language: the project and event by name, the prize categories entered, anything MLH refused and why, and what comes next. Leave out ids, timestamps, and raw status values unless the user asks for them. Never send fields MLH owns (submitter, submitted_at, status); the tools do not expose them.

The rules judges apply (all work during the event, public repo kept public, secrets out of the repo, AI use disclosed, stop at the deadline) are in the mlh-policies and mlh-hackers knowledge guides (see [[devrelay-knowledge]]). Check the project against them before submitting, and tell the user about any gap rather than submitting over it.

Before the user asks

The user installed DevRelay so the submission happens while the window is open. When list_my_mlh_events shows a registered or checked_in participation whose event is current and the work in this session is plausibly the project, raise it once: name the event, the submission deadline, and offer to run the chain. Do not wait for “submit my project”.

After submitting

Offer, once, to draft the write-up as a DEV post with create_article (see [[devrelay-publishing]]): a draft, published: false, with the default some_ai disclosure. Hand over the edit_url the tool returns, not url — a draft’s url carries a -temp-slug-<id> suffix that reads as broken. The user publishes from DEV. Do not claim a post was published unless create_article or update_article returned it with published: true.