Integrating Instagram Graph API with AWS Lambda: Building a Photo Aggregation System for Event Pages
What Was Done
We integrated Instagram's Graph API into an existing Lambda function to automatically surface @sailjada Instagram posts alongside guest-uploaded photos on event charter pages. The system queries Instagram's media endpoints filtered by date/time windows matching guest photo uploads, enabling a unified photo experience without manual curation.
The Lambda function shipcaptaincrew (deployed in us-east-1, AWS account 782785212866) already had dormant Instagram integration code—it returned empty arrays when environment variables were missing. This walkthrough activates that integration by obtaining and storing two critical values: IG_USER_ID (the Instagram Business Account ID) and IG_ACCESS_TOKEN (a long-lived Graph API token).
Technical Details: Authentication Flow
Instagram Graph API requires Business or Creator accounts linked to a Facebook Page. The authentication involves a multi-step token exchange process:
- Short-lived token generation: Created via the Graph API Explorer with scopes
instagram_basicandpages_show_list - IG_USER_ID retrieval: Two sequential Graph API calls—first to the Facebook Page to get the
instagram_business_accountID, then to extract the numeric user ID - Long-lived token exchange: Converts the short-lived token (valid ~2 hours) to a long-lived token (valid 60 days) using the app's credentials
Why this approach? Instagram Graph API doesn't support password-based or refresh token flows. The 60-day long-lived token requires periodic renewal (every 30-45 days as a safety margin) using the same exchange mechanism, which can be automated via EventBridge for hands-off operation.
Step 1: Add the Correct Product to Your Facebook App
The initial blocker was a misconfigured product. The app had "Messaging" added, which grants permissions for Instagram DM functionality—not media reads. This required adding the Instagram Graph API product separately:
- Navigate to
developers.facebook.com/apps - Select the
sailjada-socialapp - Click Add Product in the left sidebar
- Search for and select Instagram Graph API (distinct from Basic Display and Messaging products)
- Choose Instagram Graph API as the access type during setup
After adding the product, link the @sailjada Instagram account via API setup → Add Instagram account, logging in with the account's credentials. This establishes the business relationship required for token issuance.
Step 2: Generate Initial Short-Lived Token
Use the Graph API Explorer to obtain a short-lived access token with the correct scopes:
1. Go to developers.facebook.com/tools/explorer
2. Select "sailjada-social" app from the dropdown
3. Click "Generate Access Token"
4. Select the Facebook Page linked to @sailjada
5. Add scopes: instagram_basic, pages_show_list
6. Copy the generated token (valid for ~2 hours)
Store this temporary token in a secure location—you'll exchange it for a long-lived token in the next step.
Step 3: Retrieve IG_USER_ID via Graph API Calls
Execute two API calls using the short-lived token. First, fetch the Instagram Business Account ID from your Facebook Page:
curl -s "https://graph.instagram.com/v18.0/{PAGE_ID}?fields=instagram_business_account&access_token={SHORT_LIVED_TOKEN}"
The response contains an instagram_business_account object with an id field—this is your IG_USER_ID. Then query the Instagram Business Account directly to confirm the structure:
curl -s "https://graph.instagram.com/v18.0/{IG_USER_ID}?fields=id,username&access_token={SHORT_LIVED_TOKEN}"
Important: The numeric ID in the response (not the username) is the value you'll store as the IG_USER_ID environment variable.
Step 4: Exchange for Long-Lived Token
Convert the short-lived token to a 60-day long-lived token using your app credentials:
curl -s "https://graph.instagram.com/v18.0/access_token?grant_type=fb_exchange_token&client_id={APP_ID}&client_secret={APP_SECRET}&access_token={SHORT_LIVED_TOKEN}"
The access_token field in the response is your IG_ACCESS_TOKEN—store this value securely. The expires_in field confirms the 60-day validity window.
Infrastructure: Lambda Environment Variable Configuration
Update the shipcaptaincrew Lambda function with the two retrieved values. Use the AWS CLI to avoid exposing credentials in shell history:
aws lambda update-function-configuration \
--function-name shipcaptaincrew \
--region us-east-1 \
--environment "Variables={IG_USER_ID=,IG_ACCESS_TOKEN=,...}"
Alternatively, store these in AWS Secrets Manager and retrieve them within the Lambda handler for better security posture. The function code already contains conditional logic to check for these variables and skip Instagram integration if they're absent.
Key Architectural Decisions
- Long-lived tokens over refresh flows: Instagram Graph API doesn't support OAuth refresh tokens. The 60-day window requires periodic renewal—acceptable for a low-frequency integration like photo aggregation.
- Business Account requirement: Personal Instagram accounts don't support Graph API media access. @sailjada must remain configured as a Creator or Business account linked to a Facebook Page.
- Scope minimalism:
instagram_basic(media read) andpages_show_list(page enumeration) are the minimum scopes. No DM, comment, or story permissions are requested. - Date/time windowing in Lambda: The function filters Instagram posts by comparing timestamps to guest photo uploads, avoiding duplicate or stale content.
Verification and Next Steps
After updating the Lambda environment variables, navigate to shipcaptaincrew.queenofsandiego.com/g/2026-04-29 (or any past event date with both guest photos and Instagram posts). The page should now display Instagram media alongside uploaded photos.
For production reliability, implement a monthly token refresh scheduled via EventBridge:
- Create an EventBridge rule that triggers every 30 days
- Target a Lambda function that invokes the token exchange call and updates Secrets Manager
- Monitor CloudWatch logs for failed refreshes to catch token expiration before it impacts the live site
This eliminates manual token rotation and ensures the integration remains active across deployment cycles.