Outlook Mail Developer Platform
Build custom applications and mail integrations using our versioned REST API. Remotely authenticate, search mailboxes, send replies, and detect verification codes powered state-free by Microsoft Graph.
Quick Start
1. Log in
Navigate to our app homepage and complete the Sign in with Outlook flow using your personal account.
2. Copy Access Token
Open the Inspect Tokens panel in the mailbox sidebar and copy the current active Access Token.
3. Call the API
Send your HTTP request with the token attached in the Bearer header structure.
curl -X GET "https://outlook.zkzsoft.com/api/v1/mail/inbox" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept: application/json"
Authentication
The Developer API requires a valid Microsoft OAuth Access Token generated through the Microsoft Identity Platform. All protected routes inspect the Authorization header for a bearer credential.
Bearer Authentication Header
Refresh Token Exchanging
Access tokens generally expire after 60 minutes. Use the refresh token endpoint (unprotected) to request a fresh access token:
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refresh_token": "MC546_SN1.2.U.MsaArtifacts..."
}
API Reference
Explore details, inputs, headers, and output expectations for each REST endpoint below.
Retrieves profile data of the logged-in user.
Headers Required
Authorization: Bearer <MICROSOFT_ACCESS_TOKEN>
Response Payload (200 OK)
{
"success": true,
"data": {
"email": "john.doe@outlook.com",
"display_name": "John Doe",
"id": "a1b2c3d4...",
"userPrincipalName": "john.doe@outlook.com"
}
}
Fetches lists of emails. Supports OData sorting, selecting, and pagination.
Query Parameters
| Param | Type | Default | Description |
|---|---|---|---|
folder | string | inbox | Target folder (inbox, sent, drafts) |
top | number | 20 | Pagination count limit |
skip | number | 0 | Pagination skip count offset |
select | string | null | Comma-separated key attributes |
orderBy | string | date desc | OData ordering format |
unreadOnly | boolean | false | Filters only unread items |
Response Payload (200 OK)
{
"success": true,
"data": [
{
"id": "AQMkADAw...",
"subject": "Microsoft Security Code",
"sender": { "emailAddress": { "name": "Microsoft", "address": "no-reply@microsoft.com" } },
"bodyPreview": "Your code is 123456",
"receivedDateTime": "2026-07-25T11:01:00Z",
"hasAttachments": false,
"isRead": false
}
]
}
Queries the mailbox with a keyword search parameter.
Query Parameters
| Param | Type | Required | Description |
|---|---|---|---|
q | string | Yes | Keyword query term |
top | number | No | Items limit (default 20) |
Response Payload (200 OK)
{
"success": true,
"data": [ ... ]
}
Scans the latest 20 inbox items to isolate OTP verification codes.
Response Payload (200 OK)
{
"success": true,
"data": [
{
"messageId": "AQMkADAwATMw...",
"sender": "Microsoft Accounts",
"subject": "Your security code",
"code": "483921",
"confidence": "high",
"receivedDateTime": "2026-07-25T11:01:00Z"
}
]
}
Fetches detailed body content and attributes of a message.
Path Parameters
| Param | Type | Description |
|---|---|---|
id | string | Microsoft Graph email ID |
Response Payload (200 OK)
{
"success": true,
"data": {
"id": "AQMkADAwATMw...",
"subject": "Verification Details",
"body": { "contentType": "html", "content": "<html>...</html>" }
}
}
Exposes original, unfiltered JSON response direct from Microsoft Graph API.
Response Payload (200 OK)
{
"success": true,
"data": {
"@odata.context": "https://graph.microsoft.com/v1.0/...",
"id": "AQMkADAwATMw...",
"importance": "normal",
"webLink": "https://outlook.live.com/...",
"body": { ... }
}
}
Sends a new email message.
Request Body
{
"to": "recipient@example.com",
"subject": "Platform test",
"body": "Sent via developer API",
"isHtml": true
}
Response Payload (201 Created)
{
"success": true,
"data": { "success": true }
}
Replies to an existing message using a comment parameter.
Request Body
{
"messageId": "AQMkADAwATMw...",
"comment": "Understood. Thank you."
}
Response Payload (201 Created)
{
"success": true,
"data": { "success": true }
}
Exchanges a Microsoft Consumers OAuth refresh token for a new access token (No Bearer token required).
Request Body
{
"refresh_token": "MC546_SN1.2.U.MsaArtifacts..."
}
Response Payload (200 OK)
{
"success": true,
"data": {
"access_token": "EwBIBM...",
"refresh_token": "MC546_SN1...",
"expires_in": 3600,
"scope": "offline_access email User.Read Mail.Read Mail.Send",
"token_type": "Bearer"
}
}
Code Examples
Quick integration snippets in various modern languages.
curl -X GET "https://outlook.zkzsoft.com/api/v1/me" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept: application/json"
const getProfile = async (token) => {
const response = await fetch('https://outlook.zkzsoft.com/api/v1/me', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
});
const data = await response.json();
console.log(data);
};
const axios = require('axios');
async function fetchInbox(token) {
const response = await axios.get('https://outlook.zkzsoft.com/api/v1/mail/inbox', {
headers: { 'Authorization': `Bearer ${token}` }
});
console.log(response.data);
}
const http = require('http');
const options = {
hostname: 'localhost',
port: 3000,
path: '/api/v1/me',
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => { data += chunk; });
res.on('end', () => { console.log(JSON.parse(data)); });
});
req.end();
import axios, { AxiosResponse } from 'axios';
interface ProfileResponse {
success: boolean;
data: { email: string; display_name: string; id: string; };
}
async function getProfile(token: string): Promise {
const response: AxiosResponse = await axios.get('https://outlook.zkzsoft.com/api/v1/me', {
headers: { Authorization: `Bearer ${token}` }
});
return response.data;
}
import requests
def get_otp_list(access_token):
headers = {
"Authorization": f"Bearer {access_token}",
"Accept": "application/json"
}
response = requests.get("https://outlook.zkzsoft.com/api/v1/mail/otp", headers=headers)
print(response.json())
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://outlook.zkzsoft.com/api/v1/me");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer YOUR_ACCESS_TOKEN",
"Accept: application/json"
));
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
?>
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class MailClient {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://outlook.zkzsoft.com/api/v1/me"))
.header("Authorization", "Bearer YOUR_ACCESS_TOKEN")
.GET()
.build();
HttpResponse resp = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
}
}
package main
import (
"fmt"
"net/http"
"io"
)
func getProfile(token string) {
req, _ := http.NewRequest("GET", "https://outlook.zkzsoft.com/api/v1/me", nil)
req.Header.Set("Authorization", "Bearer " + token)
resp, _ := (&http.Client{}).Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program {
static async Task Main(string[] args) {
using (var client = new HttpClient()) {
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "YOUR_ACCESS_TOKEN");
var response = await client.GetAsync("https://outlook.zkzsoft.com/api/v1/me");
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}
}
Download Center
Acquire exportable client collections, specs, and reference manuals to load directly into testing tools.
Swagger API Documentation
Access full interactive specifications directly on our Swagger UI document context.
Interactive Swagger Hub
Allows live endpoint testing, parameter schema specifications, and visual response structures.
Error Reference Directory
400 Bad Request
Missing required attributes, or formatting mismatches (e.g. non-integer pagination inputs).
401 Unauthorized
Access token is missing, expired, or invalid. Call the refresh endpoint to obtain a fresh token.
403 Forbidden
The access token lacks delegated scopes required to perform the action (e.g., missing Mail.Read).
404 Not Found
The target Graph message ID or directory cannot be located inside the Outlook workspace.
429 Too Many Requests
Rate limit exceeded (100 requests per 15 minutes limit). Integrate cooldown delays.
500 Server Error
Internal application exceptions, or unexpected upstream service failures from Microsoft Graph.
Rate Limits & Health
Standard consumption limits enforced on all developer API routes.
100
Requests / 15 Minutes99+
Updated on query15m
Remaining windowAPI Release Changelog
-
v1.0.0 (Release Version) — 2026-07-25
Initial developer portal implementation, including CORS configurations, 10-language code examples, rate limiter metrics, search APIs, and scanning helper endpoints.
FAQ
POST request containing your refresh_token parameter to /api/v1/auth/refresh. The backend exchanges it stateless with Microsoft and returns new keys.
GET /api/v1/mail/otp fetches the latest 20 messages and runs a proximity regex scan on their subjects and previews. It identifies numeric and alphanumeric tokens situated near security-related keywords.