GitHub Copilot API Request Format: Headers and Payload Guide
A comprehensive developer guide to formatting requests for GitHub Copilot's completions and chat models. Learn required headers, JSON payload structures, and how to verify request signatures for custom developer integrations.
The authentication architecture of GitHub Copilot API requests
Developer integrations attempting to interact directly with the GitHub Copilot API will fail if they treat it like a standard LLM provider that accepts static, long-lived API keys. The Copilot API enforces a strict, multi-layered authentication architecture that separates user authorization from model inference through short-lived session tokens. Custom tooling, custom IDE extensions, and automated agent environments must replicate the exact device authorization flow and token exchange choreography to communicate with Copilot's model endpoints without connection drops.
This security model is designed to protect repository source code and audit user activity. Standard static API keys are vulnerable to leakage, as they are frequently committed to public repositories by accident or cached in insecure build logs. By requiring OAuth-based tokens that must be renewed frequently, GitHub limits the exposure window of any single credential. When an editor extension or an agent requests a code completion, it must present a valid session token obtained from the GitHub authentication service.
This token exchange mechanism splits the architecture into two distinct components: the identity provider and the completion provider. The identity provider is GitHub, which validates the developer's credentials or organization membership. The completion provider is the Copilot service, which accepts the temporary session token to generate code suggestions. Organization administrators can also configure Bring Your Own Key settings to connect custom models, but user access is always mediated through GitHub's secure permission systems.
To establish a connection, the local development client first checks for stored credentials in the local system configuration or environment variables. If a valid GitHub token is available, the client initiates a GET request to the internal GitHub Copilot token endpoint at https://api.github.com/copilot_internal/v2/token. This request contains the user's GitHub token in the authorization header. The GitHub authentication service verifies the token scopes and checks if the associated account has an active Copilot subscription. If verified, the endpoint returns a JSON payload containing a temporary session token, typically prefixed with transaction details, alongside an expiration timestamp. The local client uses this temporary token to authorize completions directly with the model gateway. The session token expires after a short duration, requiring the client to request a new token automatically. Caching this session token is critical to avoid rate-limiting issues on the GitHub API, as organizations are subject to standard API request limits.
Understanding the temporary token payload structure
When the token exchange endpoint responds with a successful HTTP 200 OK status, the JSON body contains several key parameters that the client must parse. The most critical field is token, which is a jwt-like string used as the bearer token for subsequent completions requests. Additionally, the payload includes an expires_at Unix epoch timestamp, which indicates exactly when the session token will expire. The client must implement a timer or checking mechanism to refresh this token before it expires, typically initiating a refresh request five minutes prior to the expiration limit to ensure uninterrupted service.
The payload also carries metadata about the user's entitlements, such as whether they have access to specific models or chat features. The client must store these token parameters securely in memory. If the token is written to disk, it should be placed in user-restricted paths (such as the developer's local app data directory) and protected with file permissions that prevent read access from other system processes.
Related guides
- How to Use the Manus AI API for Agent TasksFiles uploaded through the Manus API are automatically deleted 48 hours after upload, so production integrations need...
- How to Use the Claude Code API and Agent SDKThe Claude Code Agent SDK gives developers the same tools, agent loop, and context management that power Claude Code,...
- GitHub Copilot API Key: Authentication and SDK Setup GuideA comprehensive developer guide to GitHub Copilot's authentication architecture. Learn why Copilot avoids static API...
- How to Query the GitHub Copilot API with External Tool ContextQuerying the Copilot API with external context allows developers to pass custom file systems, test outputs, and...
- GitHub Copilot API Developer Guide: Uptime, Metrics, and Agent IntegrationAn in-depth developer guide to the GitHub Copilot REST API. Learn how to manage seats programmatically, download daily...
- How to Ground GitHub Copilot with GitHub API DocumentationGrounding GitHub Copilot with the official GitHub API documentation ensures that the assistant generates up-to-date and...
More on this subject: GitHub Copilot (130 guides)
How to format the Copilot request headers with required version parameters
Once a client has retrieved a valid session token, it must structure its HTTP request headers according to GitHub's specific REST API conventions. Outbound requests to the completions endpoint require a combination of authorization details, content type specifications, and version parameters. Failing to supply the correct version parameters will cause the request to default to an older API version, which might not support the desired models or capabilities. Requests without the X-GitHub-Api-Version header will default to use the 2022-11-28 version. Specifying the version ensures that your integration remains stable even when breaking changes are introduced to the API.
To make a successful request to the model gateway, the client must include the following headers:
Authorization: Bearer<session_token>(The temporary session token retrieved from the token endpoint)Content-Type:application/json(Required for all POST requests containing a JSON payload)X-GitHub-Api-Version:2022-11-28(Explicitly defines the API version to prevent default fallback issues)Copilot-Integration-Id:vscode-chat(Or a similar editor identifier that identifies the client plugin)Editor-Version:vscode/1.98.0(Identifies the version of the editor host application)Editor-Plugin-Version:copilot-chat/0.23.2(Identifies the specific version of the Copilot plugin)User-Agent:GitHubCopilotChat/0.23.2(Identifies the client agent making the request)
Here is a complete cURL command demonstrating how to format these headers for a chat completions request:
curl -X POST https://api.githubcopilot.com/chat/completions \
-H "Authorization: Bearer tid_12345abcdef" \
-H "Content-Type: application/json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Copilot-Integration-Id: vscode-chat" \
-H "Editor-Version: vscode/1.98.0" \
-H "Editor-Plugin-Version: copilot-chat/0.23.2" \
-d '{
"messages": [{"role": "user", "content": "Explain binary search."}],
"model": "gpt-4o",
"stream": false
}'
The model gateway uses these headers to route the request, enforce rate limits, and select the correct inference environment. If the client makes request formatting errors, the API returns standard HTTP status codes, such as 401 Unauthorized for token issues or 400 Bad Request for missing headers.
Managing header metadata for telemetry and auditing
While the authorization and content type headers are mandatory for connection, the telemetry headers such as Editor-Version and Editor-Plugin-Version are important for administrative auditing. Organization administrators can inspect Copilot usage logs in the GitHub enterprise console. These logs capture the client identifiers passed in the headers, allowing administrators to monitor which editor versions are active across the development team. Specifying accurate telemetry headers ensures that custom tools are tracked correctly in the organization's compliance dashboards.
Manage Copilot API request formats in Fastio
Connect your custom integrations and coordinate your agents using the correct GitHub Copilot API request format in a shared workspace. Starts with a 14-day trial, credit card required.
What is the correct payload structure for completions and chat requests
The request body sent to the GitHub Copilot model gateway must be structured as a JSON payload that mirrors the OpenAI Chat Completions API specification. This ensures compatibility with standard completions libraries and allows developers to adapt existing LLM client code with minimal changes. The payload configuration varies depending on whether the client is requesting single-line code suggestions or participating in an interactive chat session.
For chat completions, the primary parameter is the messages array, which holds the dialogue history. Each message object in the array must specify a role (such as system, user, or assistant) and the text content of the message. The gateway also accepts optional parameters to control model behavior and output characteristics. Developers configure parameters like temperature to control randomness, max tokens to set limit on response length, and stream to enable server-sent events. Here is a typical JSON payload structure for an interactive chat request:
{
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": "You are a helpful coding assistant."
},
{
"role": "user",
"content": "How do I reverse a linked list in Python?"
}
],
"stream": true,
"temperature": 0.2,
"max_tokens": 1000
}
When the payload requests streaming, the gateway responds with chunked data transfer. The connection remains open while the model writes response tokens, using Server-Sent Events (SSE) to send data chunks. Each chunk contains a JSON string with the delta of the generated tokens, letting the client render the response in real time. If streaming is disabled, the gateway waits until the complete response is generated before returning a single, consolidated JSON payload.
Handling parameters for model selection and configuration
The model field in the payload determines which large language model generates the response. Depending on the user's subscription tier and organization settings, available models may include different versions of OpenAI's GPT models or Anthropic's Claude models. Custom integrations should query the models endpoint first to determine which models are enabled for the current user session before hardcoding model parameters. Specifying an unsupported model will cause the gateway to return an HTTP 400 Bad Request error.
Securing custom integrations with ECDSA signature verification
When building custom Copilot Extensions or developer agents that receive events from Copilot Chat, implementing request verification is a critical security requirement. Because your extension runs as an HTTP service exposed to the web, you must ensure that incoming requests originate from GitHub and have not been tampered with. GitHub signs every outbound request to your extension using an Elliptic Curve Digital Signature Algorithm (ECDSA) with a P-256 curve over the raw request body.
To verify requests, your server must parse specific headers and retrieve GitHub's public verification keys dynamically. GitHub includes two headers in every request sent to your service:
X-GitHub-Public-Key-Identifier(The identifier of the key used to sign the request)X-GitHub-Public-Key-Signature(The base64-encoded ECDSA P-256 signature)
Your verification middleware must perform the following steps:
Extract the key identifier and signature from the incoming headers.
Fetch the current list of verification keys from the GitHub public endpoint at
https://api.github.com/meta/public_keys/copilot_api.Find the key matching the header's identifier and convert it to a usable PEM public key format.
Verify the signature against the raw, unparsed request body using the ECDSA P-256 algorithm.
Here is an example Node.js function demonstrating how to perform this signature verification using the native node:crypto module:
import crypto from "node:crypto";
function verifyGithubSignature(
rawBody,
signature,
publicKeyPem
) {
const verifier = crypto.createVerify("SHA256");
verifier.update(rawBody);
return verifier.verify(
{
key: publicKeyPem,
dsaEncoding: "ieee-p1363"
},
Buffer.from(signature, "base64")
);
}
To prevent timing attacks and avoid fetching keys on every request, your service should cache the public keys in memory. If a request carries a key identifier that is not in your cache, your service should fetch the keys again to handle key rotations. If verification fails, your middleware must return an HTTP 401 Unauthorized status immediately and stop processing the request.
Best practices for raw request body parsing
A common implementation pitfall is attempting to verify the signature after parsing the request body as JSON. JSON parsers can reorder object keys or alter whitespace, modifying the character sequence and causing signature verification to fail. Your server must capture the raw, unparsed request bytes directly from the socket stream before any body-parsing middleware is executed. This raw byte array is the exact data that must be passed to the signature verification function.
Handoff to human review and coordinating coding agents in Fastio workspaces
While GitHub Copilot assists with code completion and extension workflows, coding agents require a structured environment to save output assets, preserve configurations, and collaborate with human developers. Standard cloud storage services or local directories lack the specialized coordination tools needed to manage multi-agent pipelines. Local files are easily overwritten, and human teams struggle to track what changes an agent made.
Fastio provides shared workspaces designed to coordinate human and agent activity. Teams configure their coding agents (such as Claude Code, Codex, Cursor, Gemini, Cline, or Manus) to write outputs directly to an agent storage workspace. Fastio features a remote Model Context Protocol (MCP) server that exposes toolsets over Streamable HTTP at https://mcp.fast.io/mcp/code, with setup instructions in the Fastio documentation. Interactive clients sign in with OAuth in the browser, while headless code sends an Authorization: Bearer <api key> header on the connection. This allows agents to read and write files programmatically, query context, and trigger workflows.
To manage configuration data or extracted documentation, teams use Metadata Views. This structured extraction layer allows teams to turn documents into a queryable database. Users describe the columns they need in plain English, and the AI designs a typed schema (such as Text, Integer, Date, or JSON) to match files in the workspace and populate a spreadsheet. For details on document data extraction, refer to the Metadata Views product page.
Fastio ensures that agent work is fully auditable. Every file change is captured in the per-file version history, allowing developers to restore previous code states if a generation error occurs. Collaborative Notes bring real-time co-editing to the workspace, letting humans and agents edit requirements documents together with multiplayer cursors. All actions are logged in the append-only audit log, establishing a clear chain of custody.
Every organization starts with a 14-day free trial, which requires a credit card to activate. Fastio offers three subscription plans: Starter at $9.99/mo, Business at $49.99/mo, and Enterprise at $199.99/mo. For detailed plan descriptions, developers check the official pricing page. This usage-based credit model allows teams to scale storage, transfer bandwidth, and access consolidated MCP tools as their development needs grow. If a developer is building a system for a client, they can build the workspace under their agent account, configure the project, and use ownership transfer to hand the organization over to the client once the setup is complete.
Automated data import from legacy cloud providers
To ease migration, Fastio supports cloud import. Development teams can perform a one-time import of legacy repositories, documentation folders, or design assets from Google Drive, Dropbox, OneDrive, and Box. This OAuth-based import preserves folder structures, ensuring that agents can locate config files immediately. Once imported, files are indexed automatically by Intelligence Mode, making them queryable for semantic search and Q&A with citations.
Sources
References used to verify factual claims in this guide.
-
Requests without the X-GitHub-Api-Version header will default to use the 2022-11-28 version.
Frequently Asked Questions
What is the API endpoint for GitHub Copilot?
GitHub Copilot's core model completion and chat endpoint is located at `https://api.githubcopilot.com/chat/completions`. Programmatic requests must be authenticated using a short-lived session token obtained from the internal token exchange service.
How do I authenticate requests to GitHub Copilot API?
To authenticate requests, your client must first exchange a valid GitHub access token (such as a Personal Access Token or OAuth token) for a short-lived session token by making a GET request to `https://api.github.com/copilot_internal/v2/token`. You then include this session token in the `Authorization: Bearer` header of your requests to the model gateway.
How do I verify request signatures from GitHub Copilot?
Every request sent to a Copilot Extension is signed with an ECDSA signature over the raw request body. You must retrieve the public verification keys from `https://api.github.com/meta/public_keys/copilot_api` and use the ECDSA P-256 algorithm to verify the signature in the `X-GitHub-Public-Key-Signature` header against the raw body bytes.
Related Resources
Manage Copilot API request formats in Fastio
Connect your custom integrations and coordinate your agents using the correct GitHub Copilot API request format in a shared workspace. Starts with a 14-day trial, credit card required.