Search code examples
instagraminstagram-apiinstagram-graph-api

Check if Instagram Photo Access URL has Expired


I am fetching Instagram images from the Graph API, specifically the IG User Media endpoint

request:

GET /me/media/?
    access_token=<token>&
    fields=id,caption,media_type,media_url,permalink,timestamp,username

The media URLs are saved into the db, and are of the form:

https://scontent-iad3-1.cdninstagram.com/v/t51.29350-15
  /336488XXX_42796964621XXXX_411090403787759XXXX_n.jpg?
    _nc_cat=107&
    ccb=1-7&
    _nc_sid=8ae9d6&
    _nc_ohc=Pji5XmNsjN4AX-9CEpw&
    _nc_ht=scontent-iad3-1.cdninstagram.com&
    edm=ANo9K5cEAAAA&
    oh=00_AfCauzwgMIg6CNeeGLrt9OwVmW72sy9ndxgaMYciKOHxhw&
    oe=650CEAF2

Now, these URLs expire after a certain amount of time.
The issue is I have no idea what that time period is.

The urls can be updated with a chron job ever x hours, but then the options are:

  • update every single url in the db
  • know when urls are expiring
  • fetch a fresh url every time a user loads the page, but that seems overkill

After a few tests, it looks like multiple calls to fetch an asset in a short timespan (~1 hour, maybe longer) returns the exact same url.
My understanding is that further complicates things since it means the urls don't expire based on when they are requested but instead have fixed windows.

Can the expiry time be derived from the url parameters?
Is there any documentation about the specifics of how Instagram handles URL expiry?


Solution

  • Turns out the oe url parameter contains the expiry timestamp encoded in hex.

    To check when the url expires in JavaScript/TypeScript:

    export function isIgMediaUrlValidTill(
      mediaUrl: string | URL,
      till: Date = new Date()
    ): boolean {
      let url = new URL(mediaUrl);
      let urlExpiryTimestamp = parseInt(url.searchParams.get("oe") ?? "0", 16);
      let tillTimestamp = Math.floor(till.getTime() / 1000);
      return tillTimestamp <= urlExpiryTimestamp;
    }