# GitHub Issues

Open a GitHub issue from each submission.

## GitHub Issues

Turn submissions into GitHub issues automatically. Each submission creates one issue in the repository you choose, with a custom title, body, and milestone.

<h2 id="what-you-get">What you get</h2>

<ul>
  <li>One GitHub issue per submission, attributed to the connecting user</li>
  <li>
    Title and body built from a template editor — type <strong>@</strong> to insert any form field value
  </li>
  <li>Body supports GitHub-flavored markdown (bold, lists, headings, code fences, links)</li>
  <li>Optional default milestone applied to every issue</li>
  <li>
    Test button that creates a real <code>[Test]</code>-prefixed issue so you can verify before going live
  </li>
</ul>

<h2 id="connect">Connect GitHub</h2>

<h2 id="abandoned-responses">Abandoned response events</h2>

<p>
  When a respondent starts your form but doesn't finish, formbase can create a separate issue for the partial data. Set{' '}
  <strong>Send abandoned event after</strong> to 12 hours, 1 day, 3 days, or 1 week, then fill in the abandoned issue title and body —
  neither can be empty. Abandoned issues get a <code>partial-submission</code> label, created on first use.
</p>

<p>
  An hourly sweep looks for idle drafts, so the issue appears at the first sweep after the window passes. Only drafts from a share link are
  swept, and <strong>Required fields</strong> narrows it further: the issue is created only when at least one of the fields you pick was
  filled in.
</p>

> ℹ️ **Pro feature**
> <p>
>     Abandoned response delivery requires a Pro or Business plan. The core GitHub Issues integration is available on all plans. See{' '}
>     <a href="/subscription-billing/plans-pricing">plans & pricing</a>.
>   </p>

<h2 id="tokens">Tokens</h2>

<p>
  GitHub OAuth App tokens <strong>do not expire</strong> — there is no refresh-token rotation. If you revoke the grant from your GitHub
  account's authorized OAuth Apps page, the next dispatch fails, formbase marks the credential as expired, and you receive a failure
  notification email. Reconnect from the workspace Integrations page to restore.
</p>

<h2 id="removing">Removing the integration</h2>

<ul>
  <li>
    <strong>From formbase</strong> — Form settings → Integrations → GitHub Issues → Delete. New submissions stop creating issues
    immediately.
  </li>
  <li>
    <strong>From GitHub</strong> — Revoke the OAuth grant from your account's authorized OAuth Apps page. formbase does not automatically
    revoke the token on its side.
  </li>
</ul>

<h2 id="limits">Limits and behavior</h2>

<ul>
  <li>One issue per submission — no comment-on-existing-issue mode</li>
  <li>No backfill — only new submissions create issues</li>
  <li>Title is plain text, truncated with an ellipsis past 256 characters; body is markdown-only</li>
  <li>
    An empty title falls back to <code>New submission to &lt;form name&gt;</code>
  </li>
  <li>File upload answers render as the file name followed by its download link, so the file is reachable from the issue</li>
  <li>
    Respondent answers are inserted into the issue body as-is — if an answer contains <code>@username</code>, GitHub notifies that user, and{' '}
    <code>#123</code> creates an issue reference
  </li>
</ul>

<h2 id="faq">FAQ</h2>

  <p>
    Three GitHub scopes: <code>repo</code> (create issues), <code>read:user</code> (identify your account), and <code>read:org</code> (list
    organization repos). This is a standard OAuth App — no GitHub App installation required.
  </p>

  <p>
    Yes. GitHub connections are workspace-scoped. Any workspace member can use any connected GitHub account when setting up an integration.
  </p>

  <p>
    Yes. Open the integration detail sheet and change either field. Switching repositories resets the milestone since milestones are
    repo-specific.
  </p>

  <p>
    The next submission fails with a "not found" error and the integration shows an error status. Edit the integration to pick a different
    repository.
  </p>

  <p>
    The integration auto-pauses and an email goes to the person who set it up. A revoked token, a lost permission, or a deleted repository
    does not wait for five failures — it stops the integration immediately. Either way, fix the cause and press Resume.
  </p>

<h2 id="next-steps">Next steps</h2>
<div class="not-prose grid gap-3 sm:grid-cols-2">
  - [Developer overview](/developers/overview) — REST API, webhooks, and MCP server
  - [Plans & pricing](/subscription-billing/plans-pricing) — Compare Free, Pro, and Business features
</div>
