Stop Updating PKPass from Wallet

For our project we publish and endpoint to update a PKPass from wallet. It works fine. We are facing a problem with expired passes, due to the Automatic Updates configuration in each device our server received a lot request included those from expired passes. I cannot find any configuration inside the pass to avoid this request to my server.

Answered by DTS Engineer in 893642022

Hi @frednavarrete@seven4n.com,

You wrote:

[...] We are facing a problem with expired passes, due to the Automatic Updates configuration in each device our server received a lot request included those from expired passes. I cannot find any configuration inside the pass to avoid this request to my server.

There is no static field inside the pass.json to preemptively disable update polling. However, the solution is controlled via your server's HTTP response, not the pass itself. Here are your options:

  • Return a voided pass without webServiceURL
  • Proactively push the update before polling starts
  • Respond with HTTP 401

Return a voided pass without webServiceURL

When you server receives a GET /v1/passes/{passTypeIdentifier}/{serialNumber} request for an expired pass, respond with HTTP 200 and a new pass payload that:

  • Sets the voided field to true
  • Removes the webServiceURL and authenticationToken fields entirely
{
  "passTypeIdentifier": "pass.com.yourcompany.example",
  "serialNumber": "abc123",
  "expirationDate": "2026-01-01T00:00:00Z",
  "voided": true
  // No webServiceURL or authenticationToken
}

By omitting those two fields, Wallet unsubscribes from future updates for that pass and stops polling your server entirely.

Proactively push the update before polling starts

When a pass expires on your side, proactively send a push notification to all registered devices for that pass. On the subsequent GET request, return the voided pass without webServiceURL as described above. This is cleaner because it handles it immediately rather than waiting for the next polling cycle.

Respond with HTTP 401

Returning HTTP 401 on the get-pass endpoint signals to Wallet that the authentication token is no longer valid. Wallet will remove the web service registration for that pass and stop sending update requests.

Warning: Use this as a last resort since it's more abrupt and the behavior may vary slightly across iOS versions.

The most robust approach is a combination of proactive push when the pass expires and returning HTTP 200 with a pass where voided is true and no webServiceURL is provided. This ensure the pass is correctly marked in Wallet and polling stops permanently for that pass, reducing load on your server over time.

Cheers,

Paris X Pinkney |  WWDR | DTS Engineer

Can you expand on what you mean by "expired"? Expired by "relevantDates" (so, hidden in wallet) or expired by "expirationDate" and/or "voided"?

Not sure if there's any difference in terms on updates when a pass becomes voided or expires, but it would make sense.

For what I know there is no option to disable updates when a pass expires, but if you find it, let me know! I'm curious

Hi @frednavarrete@seven4n.com,

You wrote:

[...] We are facing a problem with expired passes, due to the Automatic Updates configuration in each device our server received a lot request included those from expired passes. I cannot find any configuration inside the pass to avoid this request to my server.

There is no static field inside the pass.json to preemptively disable update polling. However, the solution is controlled via your server's HTTP response, not the pass itself. Here are your options:

  • Return a voided pass without webServiceURL
  • Proactively push the update before polling starts
  • Respond with HTTP 401

Return a voided pass without webServiceURL

When you server receives a GET /v1/passes/{passTypeIdentifier}/{serialNumber} request for an expired pass, respond with HTTP 200 and a new pass payload that:

  • Sets the voided field to true
  • Removes the webServiceURL and authenticationToken fields entirely
{
  "passTypeIdentifier": "pass.com.yourcompany.example",
  "serialNumber": "abc123",
  "expirationDate": "2026-01-01T00:00:00Z",
  "voided": true
  // No webServiceURL or authenticationToken
}

By omitting those two fields, Wallet unsubscribes from future updates for that pass and stops polling your server entirely.

Proactively push the update before polling starts

When a pass expires on your side, proactively send a push notification to all registered devices for that pass. On the subsequent GET request, return the voided pass without webServiceURL as described above. This is cleaner because it handles it immediately rather than waiting for the next polling cycle.

Respond with HTTP 401

Returning HTTP 401 on the get-pass endpoint signals to Wallet that the authentication token is no longer valid. Wallet will remove the web service registration for that pass and stop sending update requests.

Warning: Use this as a last resort since it's more abrupt and the behavior may vary slightly across iOS versions.

The most robust approach is a combination of proactive push when the pass expires and returning HTTP 200 with a pass where voided is true and no webServiceURL is provided. This ensure the pass is correctly marked in Wallet and polling stops permanently for that pass, reducing load on your server over time.

Cheers,

Paris X Pinkney |  WWDR | DTS Engineer

Stop Updating PKPass from Wallet
 
 
Q