📌 Microsoft Graph API: Email Pinning Workaround

0 comments0 reviews

Microsoft Graph does not have a native endpoint for pinning emails. Instead, official Outlook clients track the pinned state under the hood using a low-level MAPI property called PidTagRenewTime.

#The "Magic" Mechanics

  • Property Tag: SystemTime 0x0F02
  • Pinned State: Outlook sets this timestamp to the far-future date: 4500-01-01T00:00:00Z.
  • Unpinned State: Outlook resets this timestamp to the email's original receivedDateTime.

#1. Fetching Pin Status (GET)

To read the pinned status, you must explicitly expand the target MAPI property using an OData filter.

GET https://microsoft.com
  ?$expand=singleValueExtendedProperties($filter=id eq 'SystemTime 0x0F02')
  &$top=20

📋 UI Parsing Logic

Iterate through the returned singleValueExtendedProperties array for each message:

const isPinned = message.singleValueExtendedProperties?.some(
  prop => prop.id === "SystemTime 0x0F02" && prop.value.startsWith("4500")
);

if (isPinned) {
  // 1. Render pin icon in UI
  // 2. Anchor/Sort to the top of the folder list
}

#2. Pinning an Email (PATCH)

To pin a message so it syncs natively back to official Outlook clients, update its MAPI property to the year 4500.

PATCH https://microsoft.com{message-id}
Content-Type: application/json

{
  "singleValueExtendedProperties": [
    {
      "id": "SystemTime 0x0F02",
      "value": "4500-01-01T00:00:00Z"
    }
  ]
}

#3. Unpinning an Email (PATCH)

To unpin a message, update its value back to the email's original receivedDateTime.

PATCH https://microsoft.com{message-id}
Content-Type: application/json

{
  "singleValueExtendedProperties": [
    {
      "id": "SystemTime 0x0F02",
      "value": "2026-09-22T14:44:00Z" 
    }
  ]
}

  1. SDK Serialization Issues: Official Microsoft Graph SDK libraries (especially .NET and TypeScript/Graph Client) frequently fail to serialize nested singleValueExtendedProperties collections properly during PATCH requests. If updates silently fail, bypass the SDK models and drop down to a raw HTTP request.
  2. Case Sensitivity: The returned property ID string is strictly case-sensitive (SystemTime 0x0F02). Ensure parsing matches exact casings.
  3. No Unpin Deletion: Do not attempt to clear or delete the property to unpin; Outlook explicitly expects a valid timestamp string to sort it back down chronologically.