Integrating Instagram Graph API with AWS Lambda: Connecting @sailjada Media to Guest Photo Pages
What Was Done
We enabled Instagram media integration for the guest photo page system at shipcaptaincrew.queenofsandiego.com/g/{event_id}. Previously, the Lambda function had dormant Instagram integration code that returned empty arrays when credentials were missing. We've now established the full authentication pipeline to populate guest event pages with @sailjada Instagram posts from matching date/time windows, displayed alongside user-uploaded charter photos.
Technical Architecture
The solution involves three key components:
- Facebook App Configuration: A Meta Developer app (
sailjada-social) configured with Instagram Graph API product, properly scoped for media reads - Token Exchange Pipeline: Short-lived token generation → User ID lookup → Long-lived token exchange (60-day validity)
- Lambda Environment Variables: The existing
shipcaptaincrewLambda function (us-east-1, account 782785212866) updated withIG_USER_IDandIG_ACCESS_TOKEN
Step-by-Step Setup
1. Add the Correct Product to Your Meta App
This is the critical first step. Many developers add "Messaging" or "Basic Display" — both of which lack the instagram_basic scope needed to read media endpoints.
- Navigate to
developers.facebook.com/apps - Select your app (
sailjada-social) - In the left sidebar, click Add Product
- Search for Instagram and select Instagram Graph API (the full API, not Basic Display)
- Complete setup — it will appear in your left sidebar
2. Link Your Instagram Business Account
The @sailjada account must be a Business or Creator account (not a personal account) and linked to a Facebook Page. To verify:
- In Instagram Graph API settings, click API setup with Instagram login
- Click Add Instagram account
- Authenticate as @sailjada. If you see "This account is not eligible," convert it to a Business account first
- Once linked, note the associated Facebook Page ID
3. Generate a Short-Lived Access Token
We generate a short-lived token first to obtain the User ID, then exchange it for a 60-day token. Use the Graph API Explorer:
- Visit
developers.facebook.com/tools/explorer - In the top dropdown, select your app:
sailjada-social - Click Generate Access Token
- When prompted for permissions, select the Facebook Page linked to @sailjada
- In the scopes panel, ensure
instagram_basicandpages_show_listare checked - Copy the generated token (valid for ~2 hours)
4. Retrieve the Instagram User ID
With your short-lived token, make two API calls. First, get the Page's connected Instagram business account:
curl -X GET "https://graph.instagram.com/v18.0/{PAGE_ID}?fields=instagram_business_account&access_token={SHORT_LIVED_TOKEN}"
The response includes an instagram_business_account object with an id field — this is your IG_USER_ID. Save this value.
5. Exchange for a Long-Lived Token
Short-lived tokens expire in 2 hours. Exchange it for a 60-day long-lived token using your app credentials (stored securely in your deployment pipeline):
curl -X GET "https://graph.instagram.com/v18.0/access_token?grant_type=ig_exchange_token&client_id={APP_ID}&client_secret={APP_SECRET}&access_token={SHORT_LIVED_TOKEN}"
The response includes a new access_token (60-day validity) — this is your IG_ACCESS_TOKEN.
Infrastructure & Lambda Configuration
Update the shipcaptaincrew Lambda function with the credentials:
aws lambda update-function-configuration \
--function-name shipcaptaincrew \
--region us-east-1 \
--environment Variables='{
"IG_USER_ID":"",
"IG_ACCESS_TOKEN":"",
"IG_TIME_WINDOW_HOURS":"6"
}'
The existing Lambda code checks for these variables and, when present, fetches recent Instagram media from the @sailjada account using the endpoint:
GET https://graph.instagram.com/v18.0/{IG_USER_ID}/media?fields=id,caption,media_type,media_url,timestamp&access_token={IG_ACCESS_TOKEN}
The Lambda filters results by timestamp, matching posts within the event's date/time window.
Token Refresh Strategy
Instagram long-lived tokens expire after 60 days. Implement monthly refresh using the same exchange endpoint — no user re-authentication required. Options:
- EventBridge Schedule: Trigger a Lambda monthly to refresh and update environment variables
- Manual Refresh: Run the exchange call quarterly and update via the AWS CLI or Lambda console
- Application-Level Caching: Cache the token in a DynamoDB table with TTL, refresh on expiry
We recommend the EventBridge approach for production — it removes manual intervention and centralizes token management.
Why These Design Decisions
- Graph API over Basic Display: Graph API provides timestamp filtering, caption text, and media type — critical for matching Instagram posts to event windows. Basic Display only returns a URL.
- 60-Day Tokens Over User Tokens: User-generated access tokens require re-authentication every 60 days. We generate them once, then exchange for app-controlled 60-day tokens that can be refreshed without user involvement.
- Lambda Environment Variables: Storing credentials in Lambda env vars (encrypted at rest by AWS KMS) keeps them separate from code. Secrets Manager is overkill for non-rotating, non-sensitive tokens in this context.
- Time Window Filtering in Lambda: The API returns all media; filtering by event timestamp in the Lambda function (not in the query) gives us flexibility to adjust window logic without re-deploying infrastructure.
Verification & Testing
After deploying credentials, test the integration:
- Navigate to
shipcaptaincrew.queenofsandiego.com/g/2026-04-29(or any event date) - Look for Instagram posts from @sailjada in the photo feed