Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article specifies the protocol for integrating first and third-party applications with the Windows Snipping Tool using the ms-screenclip: URI (Uniform Resource Identifier) scheme. The protocol supports the capture of images and video (with audio) via Snipping Tool, and app callers can choose which Snipping Tool features their app will display.
Important
This protocol requires a packaged Windows app (MSIX). When your app is packaged, the operating system automatically provides your app's identity to Snipping Tool, which uses it to securely route the capture response back to your app. Unpackaged (Win32) callers cannot receive responses via redirect-uri. If an unpackaged app provides a redirect-uri, Snipping Tool will not deliver the response and may exit without showing the capture UI.
Note
This protocol replaces the experience documented in Launch screen snipping (Deprecated), which is now deprecated.
Supported features
The Snipping Tool protocol supports the following features:
- Rectangle Capture
- Freeform Capture
- Window Capture
- Screen Recording
- Customizing available capture modes
- Auto-save (optional)
Protocol specification
URI Format: ms-screenclip://{host}/{path}?{query parameters}
| Component | Description | Values |
|---|---|---|
| Scheme | The custom scheme for Snipping Tool | ms-screenclip |
| Host | The Snipping Tool operation to perform | capture or discover |
| Path | The media type to capture (applies to the capture host only; the discover host has no path) |
/image or /video |
| Query | Parameters for the operation | See tables below |
Note
Paths and query parameter names are case-insensitive. For example, ms-screenclip://capture/Image?Redirect-Uri=my-app://response behaves the same as ms-screenclip://capture/image?redirect-uri=my-app://response.
Capture host
Use the capture host to launch Snipping Tool's capture overlay.
Path
| Path | Description |
|---|---|
/image |
Launches image capture (screenshot). Requires a mode parameter. |
/video |
Launches video capture (screen recording). Always uses rectangle mode. |
Mode parameters (capture/image)
For the /image path, you must specify exactly one mode parameter. Mode parameters are bare query parameters with no value.
| Parameter | Description |
|---|---|
rectangle |
Interactive rectangle capture mode. |
freeform |
Interactive freeform capture mode. |
window |
Interactive window capture mode. |
Important
Mode parameters must be specified without a value. For example, use &rectangle, not &rectangle=value. Providing a value will result in an error response.
For /image, you must specify exactly one mode parameter. Specifying zero or more than one mode will result in a 400 Bad Request error response. For /video, any mode parameter is ignored.
Query parameters (capture)
Note
Query parameters may be provided in any order.
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
redirect-uri |
URI | Yes | Callback URI where Snipping Tool sends the capture response. Your app must register a protocol handler for this URI scheme. If omitted, Snipping Tool doesn't display the capture UI and doesn't return a response. | n/a |
user-agent |
string | No (strongly recommended) | Identifier for the calling application, used for logging and analytics. Required to diagnose issues via support channels; omit at your own risk. | n/a |
api-version |
string | No | Protocol version to use, for example "1.2". If omitted, the request is processed as version 1.2. |
1.2 |
x-request-correlation-id |
string | No | Unique identifier for the request, allowing reference to a particular transaction or event chain. | Auto-generated GUID |
enabledModes |
string (list) | No | Controls which capture modes are available in the UI. See EnabledModes below. | Only the mode specified in the URI |
auto-save |
flag | No | When present, the captured screenshot or recording is automatically saved to the user's device. | Not present (no auto-save) |
Note
The default api-version of 1.2 doesn't change when newer protocol versions are released. Requests that omit api-version are always processed as 1.2. To use features added in a later version, set api-version to that version. We recommend specifying api-version explicitly in every request so your app stays tied to a known protocol version rather than the implicit default.
Note
When you supply api-version, it must exactly match one of the values in the /discover response's supportedVersions array (currently 1.0, 1.1, and 1.2). Any other value — including intermediate values like 1.15 or malformed values like 1.0abc — returns a 400 Bad Request response. To discover the set of versions a specific Snipping Tool build accepts, call the discover host.
Note
The auto-save flag respects the user's Snipping Tool settings. If the user has disabled automatic saving in Snipping Tool, the capture isn't saved to the device even when your request includes auto-save.
Discover host
Use the discover host to query Snipping Tool's supported capabilities, modes, and protocol version at runtime. This is useful for checking compatibility before making a capture request.
Query parameters (discover)
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
redirect-uri |
URI | Yes | Callback URI where Snipping Tool sends the capabilities response. Your app must register a protocol handler for this URI scheme. If omitted, Snipping Tool doesn't return a response. | n/a |
user-agent |
string | No (strongly recommended) | Identifier for the calling application, used for logging and analytics. | n/a |
x-request-correlation-id |
string | No | Unique identifier for the request. | Auto-generated GUID |
Discover example
ms-screenclip://discover?user-agent=MyApp&redirect-uri=my-app://response
Discover response format
The response is a JSON object appended to the redirect URI as the discover query parameter. It contains:
version: Latest protocol version this Snipping Tool build supports.defaultVersion: Protocol version assumed when a request omitsapi-version. Read this to understand how your unpinned requests are interpreted.supportedVersions: Array of protocol versions this Snipping Tool build accepts.capabilities: Array of supported capture operations, each with:path: The capture endpoint (e.g.,capture/image,capture/video).methods: Supported HTTP-like methods.parameters: Available parameters for the endpoint.description: Description of the capability.
{
"version": 1.2,
"defaultVersion": 1.2,
"supportedVersions": [1.0, 1.1, 1.2],
"capabilities": [
{
"path": "capture/image",
"methods": ["GET"],
"parameters": ["rectangle", "freeform", "window"],
"description": "Captures an image with options for shape."
},
{
"path": "capture/video",
"methods": ["GET"],
"parameters": [],
"description": "Captures a video in a defined area."
}
]
}
EnabledModes
The enabledModes parameter lets you control which capture modes are available in the Snipping Tool UI. Use it to restrict or expand the user's choices to match your application's requirements.
Supported modes
| Mode | Description |
|---|---|
RectangleSnip |
Rectangle capture mode. |
WindowSnip |
Window capture mode. |
FreeformSnip |
Freeform capture mode. |
FullscreenSnip |
Fullscreen capture mode. |
SnippingAllModes |
All image capture modes: RectangleSnip, WindowSnip, FreeformSnip, FullscreenSnip. |
RectangleRecord |
Rectangle recording mode. |
RecordAllModes |
All recording modes: currently RectangleRecord only. |
All |
All supported modes: the union of SnippingAllModes and RecordAllModes. |
Tip
All, SnippingAllModes, and RecordAllModes are aggregate values. The modes they include can change across Snipping Tool releases. An app that uses one of these values automatically picks up modes added in future releases. To keep the set of available modes fixed across updates, list the specific modes explicitly (for example, RectangleSnip,FreeformSnip).
Important
- For
/image, a mode parameter (e.g.,rectangle,freeform,window) is required in the URI, even whenenabledModesis specified. The mode parameter determines the initially selected mode. - The mode specified in the URI is always available in the UI, even if it isn't listed in
enabledModes. For example,?freeform&enabledModes=RectangleSnipmakes both freeform (from the URI) and rectangle snip available, with freeform pre-selected. - If
enabledModesis omitted, only the mode specified in the URI will be available in the UI. - For
/image, if no mode parameter is specified, the request is invalid and will result in an error, regardless ofenabledModes.
EnabledModes examples
Enable only rectangle snip:
ms-screenclip://capture/image?rectangle&enabledModes=RectangleSnip&user-agent=MyApp&redirect-uri=my-app://response
Enable rectangle and window snip:
ms-screenclip://capture/image?rectangle&enabledModes=RectangleSnip,WindowSnip&user-agent=MyApp&redirect-uri=my-app://response
Enable all snipping modes:
ms-screenclip://capture/image?rectangle&enabledModes=SnippingAllModes&user-agent=MyApp&redirect-uri=my-app://response
Enable recording mode only:
ms-screenclip://capture/video?enabledModes=RecordAllModes&user-agent=MyApp&redirect-uri=my-app://response
Enable multiple snipping and recording modes:
ms-screenclip://capture/image?freeform&enabledModes=RectangleSnip,RectangleRecord&user-agent=MyApp&redirect-uri=my-app://response
Since freeform is specified in the URI, it will be pre-selected. Users can switch between freeform, rectangle snip, and rectangle recording.
Responses
After the user completes or cancels a capture, Snipping Tool sends a response back to your application via the redirect-uri. The response is structured as URI query parameters appended to your redirect URI.
If your redirect-uri already includes query parameters (for example, my-app://response?sessionId=abc), those parameters are preserved and the response parameters are appended with &. You can use this to round-trip caller-specific state through the callback — the value sessionId=abc is echoed back in the response URI along with code, reason, x-request-correlation-id, and (for a successful capture) file-access-token.
Response parameters
| Parameter | Type | Present | Description |
|---|---|---|---|
code |
int | Always | HTTP-style status code indicating the outcome. |
reason |
string | Always | Human-readable description of the outcome. |
x-request-correlation-id |
string | Always | The correlation ID from the original request (or an auto-generated one). |
file-access-token |
string | Success only | A SharedStorageAccessManager token representing the captured media. Use this to retrieve the file. |
discover |
string | Discover only | URL-encoded JSON containing the capabilities response. |
Status codes
| Code | Reason | Description |
|---|---|---|
| 200 | Success | The capture completed successfully. A file-access-token is included in the response. |
| 400 | Bad Request - Invalid or Missing Parameters | The request could not be processed. Check that all required parameters are present and valid. |
| 408 | Request Timeout - Operation Took Too Long | The operation timed out before completion. |
| 499 | Client Closed Request - User Cancelled the Snip | The user cancelled the capture by pressing Escape or clicking away. Applies to /image and /video only. |
| 500 | Internal Server Error - Processing Failed | An unexpected error occurred during capture. |
Example responses
Successful capture:
my-app://response?code=200&reason=Success&x-request-correlation-id=aaaa0000-bb11-2222-33cc-444444dddddd&file-access-token=cccc2222-dd33-4444-55ee-666666ffffff
User cancelled:
my-app://response?code=499&reason=Client%20Closed%20Request%20-%20User%20Cancelled%20the%20Snip&x-request-correlation-id=bbbb1111-cc22-3333-44dd-555555eeeeee
Invalid request (missing mode parameter):
my-app://response?code=400&reason=Bad%20Request%20-%20Invalid%20or%20Missing%20Parameters&x-request-correlation-id=bbbb1111-cc22-3333-44dd-555555eeeeee
Full URI examples
| Use Case | URI | Description |
|---|---|---|
| Rectangle screenshot | ms-screenclip://capture/image?rectangle&user-agent=MyApp&redirect-uri=my-app://response |
Interactive rectangle capture. Result returned to caller. |
| Freeform screenshot | ms-screenclip://capture/image?freeform&user-agent=MyApp&redirect-uri=my-app://response |
Interactive freeform capture. Result returned to caller. |
| Window screenshot | ms-screenclip://capture/image?window&user-agent=MyApp&redirect-uri=my-app://response |
Interactive window capture. Result returned to caller. |
| Screen recording | ms-screenclip://capture/video?user-agent=MyApp&redirect-uri=my-app://response |
Interactive screen recording. Result returned to caller. |
| Discover capabilities | ms-screenclip://discover?user-agent=MyApp&redirect-uri=my-app://response |
Query supported features. Capabilities JSON returned to caller. |
| Rectangle with auto-save | ms-screenclip://capture/image?rectangle&auto-save&user-agent=MyApp&redirect-uri=my-app://response |
Rectangle capture with auto-save enabled. |
| Rectangle with all modes | ms-screenclip://capture/image?rectangle&enabledModes=All&user-agent=MyApp&redirect-uri=my-app://response |
Rectangle capture pre-selected, all modes available in UI. |
Launching from your app
You must use Launcher.LaunchUriAsync to launch Snipping Tool from your packaged app. Other launch methods (such as Process.Start or shell execution) will not provide your app's identity, and Snipping Tool will not deliver the response.
Step 1: Register a protocol handler
Register a custom protocol in your Package.appxmanifest so your app can receive the callback response. The protocol name must match the scheme used in your redirect-uri.
<Extensions>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="my-app" DesiredView="default">
<uap:DisplayName>My App Protocol</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
See Handle URI activation for more details on registering and handling protocol activations.
Step 2: Launch Snipping Tool
// Capture a screenshot in rectangle mode
var uri = new Uri(
"ms-screenclip://capture/image"
+ "?rectangle"
+ "&user-agent=MyApp"
+ "&redirect-uri=my-app://capture-response"
+ "&x-request-correlation-id=" + Guid.NewGuid().ToString()
);
await Launcher.LaunchUriAsync(uri);
// Record a video
var uri = new Uri(
"ms-screenclip://capture/video"
+ "?user-agent=MyApp"
+ "&redirect-uri=my-app://capture-response"
);
await Launcher.LaunchUriAsync(uri);
// Discover capabilities (returns immediately, no capture UI)
var uri = new Uri(
"ms-screenclip://discover"
+ "?user-agent=MyApp"
+ "&redirect-uri=my-app://discover-response"
);
await Launcher.LaunchUriAsync(uri);
Step 3: Handle the response
When the capture completes (or the user cancels), Snipping Tool activates your app via your redirect-uri with result parameters appended as query strings. Most integrations are already running when the response arrives — the caller launched Snipping Tool, then waited for the callback — so your app must handle both cold-start activation (the app wasn't running) and warm re-activation (the app is already running). Subscribe to both paths in App.xaml.cs.
Handle a capture response (image or video):
// In App.xaml.cs: handle protocol activation for both cold-start and warm re-activation
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
// Cold-start path: the app was launched by Snipping Tool's callback.
var activatedArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
if (activatedArgs.Kind == Microsoft.Windows.AppLifecycle.ExtendedActivationKind.Protocol)
{
if (activatedArgs.Data is Windows.ApplicationModel.Activation.IProtocolActivatedEventArgs protocolArgs)
{
_ = HandleProtocolActivationAsync(protocolArgs.Uri);
}
}
// Warm re-activation path: the app is already running when the callback arrives.
Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().Activated += (sender, e) =>
{
if (e.Kind == Microsoft.Windows.AppLifecycle.ExtendedActivationKind.Protocol &&
e.Data is Windows.ApplicationModel.Activation.IProtocolActivatedEventArgs protocolArgs)
{
_ = HandleProtocolActivationAsync(protocolArgs.Uri);
}
};
}
private async Task HandleProtocolActivationAsync(Uri uri)
{
var query = new WwwFormUrlDecoder(uri.Query);
var code = query.GetFirstValueByName("code");
var reason = query.GetFirstValueByName("reason");
if (code == "200")
{
var token = query.GetFirstValueByName("file-access-token");
var file = await SharedStorageAccessManager.RedeemTokenForFileAsync(token);
// Use the captured file (see "Retrieving captured media" below)
}
else
{
// Handle error (400, 408, 499, 500)
Debug.WriteLine($"Snipping Tool returned {code}: {reason}");
}
}
Handle a discover response:
private void HandleDiscoverResponse(Uri uri)
{
var query = new WwwFormUrlDecoder(uri.Query);
var code = query.GetFirstValueByName("code");
if (code == "200")
{
var discover = query.GetFirstValueByName("discover");
// discover contains a URL-encoded JSON capabilities payload
var capabilities = Uri.UnescapeDataString(discover);
// Parse the JSON to inspect supported capture modes
}
}
Tip
If you sent an x-request-correlation-id with the request, verify that the response echoes the same value so you can match the response to the correct in-flight request. If you let Snipping Tool auto-generate one, the response carries the generated value — treat it as matching your most recent in-flight request.
Retrieving captured media using the token
Use the SharedStorageAccessManager class to redeem the file-access-token and access the captured file.
Token restrictions:
- A token can only be redeemed once. After redemption, it is no longer valid.
- A token expires after 14 days.
- An app cannot have more than 1000 active tokens. After a token is redeemed, removed, or expires, it no longer counts against the quota.
// Redeem the token and display the captured image
var file = await SharedStorageAccessManager.RedeemTokenForFileAsync(token);
using (var stream = await file.OpenReadAsync())
{
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(stream);
MyImage.Source = bitmap;
}
// Or copy to your app's local storage
var localFolder = ApplicationData.Current.LocalFolder;
await file.CopyAsync(localFolder, file.Name, NameCollisionOption.GenerateUniqueName);
Security considerations
Snipping Tool validates all redirect-uri values before launching them. The following protections are enforced:
- Packaged app callers: When your app is a packaged Windows app (MSIX), the operating system securely routes the capture response back to your app, ensuring only your app can receive it. This is the recommended integration path.
- Input validation: Snipping Tool rejects redirect URIs that contain UNC paths, leading/trailing whitespace, or control characters.
- No fragments: Redirect URIs that contain a URL fragment (for example,
my-app://response#section) are rejected. Snipping Tool appends the response parameters as a query string, and a fragment would swallow them. - Self-referencing protection: Redirect URIs that would cause recursive activation of Snipping Tool are blocked.
Important
For calling applications:
- Register a protocol handler for your redirect URI scheme so your app can receive the response.
- Validate and sanitize all parameters received in the response before processing them.
- Verify that the response's
x-request-correlation-idmatches your in-flight request to avoid handling a stale response or mixing up concurrent requests. Correlation-id prevents mix-ups; it doesn't establish token provenance — secure token routing comes from the packaged-app callback channel.
Related content
Windows developer