Integrating Instagram Graph API with AWS Lambda: Adding Social Media Context to Guest Photo Galleries
What We Built
We extended the guest photo gallery system at shipcaptaincrew.queenofsandwich.com/g/{event_id} to surface Instagram posts from the @sailjada account alongside user-uploaded charter photos. The integration lives in a dormant Lambda function (shipcaptaincrew, us-east-1, account 782785212866) that fetches media from Instagram's Graph API when credentials are provisioned.
This post covers the multi-step process to activate that integration: configuring the Facebook Developer app, obtaining long-lived access tokens, and deploying credentials to the Lambda environment.
Technical Architecture
Why Instagram Graph API, not Basic Display?
- Graph API provides richer metadata (timestamps, captions, engagement metrics) and supports business/creator accounts — essential for correlating posts to event dates.
- Basic Display is read-only and returns only recent media without filtering capabilities.
- Messaging API is for DMs only; it will not grant the
instagram_basicscope needed to read media.
The architecture follows a three-tier pattern:
- Token Generation Layer: Facebook Graph API Explorer generates short-lived tokens; an exchange flow converts them to 60-day long-lived tokens.
- Credential Storage: Long-lived tokens are stored as Lambda environment variables (
IG_USER_ID,IG_ACCESS_TOKEN). - Media Fetch Layer: Lambda function queries Instagram Graph API at request time, filters by date/time window, and merges results into the response.
Step-by-Step Implementation
1. Add the Correct Product to Your Facebook App
Navigate to developers.facebook.com/apps, select the app (in this case, sailjada-social), and add Instagram Graph API as a product:
- Left sidebar → Add Product
- Search for Instagram
- Select Instagram Graph API (not Basic Display, not Messaging)
- Complete setup; the product will appear in your sidebar
Why this matters: Adding the wrong product (like Messaging) grants the wrong OAuth scopes and blocks access to media endpoints.
2. Verify @sailjada Account Status
Before proceeding, confirm:
- @sailjada is a Business or Creator account (not Personal)
- The account is linked to a Facebook Page (required for Graph API access)
If @sailjada is currently a Personal account, convert it via Instagram Settings → Account Type.
3. Connect the Instagram Account in the App Dashboard
Inside your sailjada-social app, navigate to Instagram Graph API → API setup with Instagram login, then click Add Instagram account and authenticate as @sailjada. This creates the linkage between the Facebook App and the Instagram account.
4. Generate a Short-Lived Access Token
Use the Facebook Graph API Explorer to mint an initial token:
- Navigate to
developers.facebook.com/tools/explorer - Select app:
sailjada-social - From the token dropdown, generate a new Access Token
- Select the Facebook Page linked to @sailjada
- Requested scopes:
instagram_basic,pages_show_list
This token is valid for ~2 hours and is used only for the next step.
5. Retrieve IG_USER_ID
With the short-lived token, query your Facebook Page to extract the Instagram Business Account ID:
curl -G https://graph.instagram.com/v18.0/{PAGE_ID} \
-d fields=instagram_business_account \
-d access_token={SHORT_LIVED_TOKEN}
Extract the id field from the instagram_business_account object. This is your IG_USER_ID.
6. Exchange for a Long-Lived Token
Short-lived tokens expire in hours. Exchange it for a 60-day long-lived token using your App ID and App Secret:
curl -G https://graph.instagram.com/access_token \
-d grant_type=ig_refresh_access_token \
-d access_token={SHORT_LIVED_TOKEN} \
-d client_secret={APP_SECRET}
The returned access_token is your IG_ACCESS_TOKEN. Store this securely.
7. Deploy Credentials to Lambda
Update the shipcaptaincrew Lambda function (us-east-1) with environment variables:
aws lambda update-function-configuration \
--function-name shipcaptaincrew \
--region us-east-1 \
--environment Variables="{IG_USER_ID={extracted_user_id},IG_ACCESS_TOKEN={long_lived_token}}"
The function code already contains conditional logic to skip Instagram integration if these variables are absent; provisioning them activates the feature.
8. Refresh Strategy
Long-lived tokens expire after 60 days. Implement a monthly refresh:
- Manual: Re-run the exchange curl command (step 6) every 55 days and redeploy to Lambda.
- Automated: Create an EventBridge rule triggering a Lambda that refreshes the token and updates environment variables. This requires additional IAM permissions for
lambda:UpdateFunctionConfiguration.
For simplicity, manual refresh is acceptable for low-traffic integrations; automate if you prefer hands-off rotation.
Lambda Function Logic
The existing shipcaptaincrew function checks for environment variables at invocation time:
if IG_USER_ID and IG_ACCESS_TOKEN are set:
query Instagram Graph API with date/time filters
merge results into photo gallery response
else:
return empty array (no Instagram posts)
The integration queries the /ig_hashtag_search or /ig_user_id/media endpoint with a timestamp filter to match posts from the event date, then combines them with guest-uploaded photos in the final response.
Key Decisions
- Environment Variables over Secrets Manager: For a dormant feature, environment variables are simpler. If the function scales to dozens of integrations, migrate to AWS Secrets Manager for centralized rotation.
- 60-Day Token Lifespan: Facebook's Graph API enforces this ceiling for business accounts. Monthly refresh is a safe cadence.
- Request-Time Fetching: Instagram