Instagram Accounts API

Overview

GET /api/v1/accounts returns the profile of the Instagram account your API key belongs to: username, display name, bio, profile picture, follower counts, and the account's status in Feedframer.

Each connected Instagram account has its own API key, and a key only reads its own account. So this endpoint always returns exactly one account, even if you have several connected on Premium. To read another account, use that account's key.

If you also need posts, you may not need this endpoint at all. GET /api/v1/me returns the same profile fields plus the posts. Use /api/v1/accounts when you only want the profile, or when you need status, instagramUserId or the timestamps below, which /me doesn't include.

Endpoint

GET https://feedframer.com/api/v1/accounts?api_key=YOUR_API_KEY

Parameters

Parameter Notes
api_key Required. Your API key, from the account's card on the Dashboard.

The endpoint takes no other parameters. Anything else in the query string is ignored.

Response format

The response follows the JSON:API resource format: a data array with one resource, and a meta object. The Content-Type is application/json.

Success response (200 OK)

{
  "data": [
    {
      "type": "instagram-accounts",
      "id": "42",
      "attributes": {
        "instagramUserId": "17841400000000000",
        "username": "your_username",
        "name": "Your Name",
        "biography": "Your bio text",
        "website": "https://example.com",
        "profilePictureUrl": "https://cdn.feedframer.com/your_username/123_profile.jpg",
        "followersCount": 1234,
        "followsCount": 567,
        "mediaCount": 89,
        "status": "ready",
        "profileLastUpdatedAt": "2026-09-30T08:00:00+00:00",
        "lastFetchAt": "2026-09-30T19:50:34+00:00"
      }
    }
  ],
  "meta": {
    "total": 1
  }
}

Top-level fields

Field Type Notes
data array Always exactly one resource: the key's account.
data[].type string Always instagram-accounts.
data[].id string Feedframer's id for the account. This is not the Instagram user id.
data[].attributes object The account's fields, below.
meta.total integer Always 1.

There are no links in the response.

Attributes

Field Type Notes
instagramUserId string Instagram's id for the account.
username string Instagram username, without the @.
name string or null Display name on Instagram.
biography string or null Bio text. May contain line breaks.
website string or null Website from the Instagram profile.
profilePictureUrl string or null Profile picture. Usually a copy on cdn.feedframer.com.
followersCount integer or null Followers.
followsCount integer or null Accounts this account follows.
mediaCount integer or null Total posts on Instagram, not just the ones Feedframer returns.
status string The account's connection status in Feedframer. See below.
profileLastUpdatedAt string or null When the profile fields were last refreshed from Instagram, ISO 8601.
lastFetchAt string or null When Feedframer last fetched the account's posts, ISO 8601. null if it hasn't yet. The same time is sent in the X-Last-Fetched-At header on /api/v1/me and /api/v1/rss.

Profile data updates

Profile fields (bio, follower counts, profile picture and so on) refresh at most once a day, when posts are fetched. profileLastUpdatedAt shows when that last happened. Posts refresh daily on Free and hourly on Premium; lastFetchAt shows the last post fetch.

Account status values

status Meaning
ready Connected and working.
importing Feedframer is importing the account's posts: just after the account is connected, or after the owner presses "Refresh Posts" on the Dashboard. The key works and serves the posts already stored.
refreshing_token Feedframer is renewing the account's Instagram access token. This happens automatically before the token expires.
invalid_token Instagram no longer accepts the account's access token, so Feedframer can't fetch new posts. The key still works and serves the last posts Feedframer stored. The Dashboard shows "Invalid Token", and the owner is emailed to reconnect. Reconnecting fixes it and keeps the same key.

A disconnected account doesn't have a status you can read. Its key returns a 401 with the code INVALID_API_KEY.

Example requests

cURL

curl 'https://feedframer.com/api/v1/accounts?api_key=YOUR_API_KEY'

JavaScript (fetch)

const apiKey = 'YOUR_API_KEY';

const response = await fetch(`https://feedframer.com/api/v1/accounts?api_key=${apiKey}`);
const body = await response.json();

if (!response.ok) {
  // Every error has an errors array with a code, e.g. INVALID_API_KEY
  throw new Error(`${body.errors[0].code}: ${body.errors[0].detail}`);
}

const account = body.data[0].attributes;
console.log(`@${account.username}: ${account.status}`);

PHP

<?php

$apiKey = 'YOUR_API_KEY';
$url = 'https://feedframer.com/api/v1/accounts?api_key=' . urlencode($apiKey);

// ignore_errors lets us read the JSON body of 4xx and 5xx responses
$context = stream_context_create(['http' => ['ignore_errors' => true]]);
$body = json_decode(file_get_contents($url, false, $context), true);

if (isset($body['errors'])) {
    $error = $body['errors'][0];
    throw new RuntimeException("{$error['code']}: {$error['detail']}");
}

$account = $body['data'][0]['attributes'];
echo "@{$account['username']}: {$account['status']}\n";

Python

import requests

api_key = 'YOUR_API_KEY'

response = requests.get(
    'https://feedframer.com/api/v1/accounts',
    params={'api_key': api_key},
)
body = response.json()

if not response.ok:
    error = body['errors'][0]
    raise RuntimeError(f"{error['code']}: {error['detail']}")

account = body['data'][0]['attributes']
print(f"@{account['username']}: {account['status']}")

Use cases

Display a profile header

<div class="profile">
  <img class="profile-pic" alt="" />
  <a class="username"></a>
  <p class="bio"></p>
  <p><span class="followers"></span> followers</p>
</div>

<script>
  const apiKey = 'YOUR_API_KEY';

  fetch(`https://feedframer.com/api/v1/accounts?api_key=${apiKey}`)
    .then((response) => response.json())
    .then((body) => {
      if (body.errors) {
        console.error(body.errors[0].code);
        return;
      }

      const account = body.data[0].attributes;

      if (account.profilePictureUrl) {
        document.querySelector('.profile-pic').src = account.profilePictureUrl;
      }

      const link = document.querySelector('.username');
      link.textContent = `@${account.username}`;
      link.href = `https://www.instagram.com/${account.username}/`;

      // textContent keeps the bio's text safe; name, bio and counts can be null
      document.querySelector('.bio').textContent = account.biography ?? '';
      document.querySelector('.followers').textContent =
        (account.followersCount ?? 0).toLocaleString();
    });
</script>

Warn when the account needs reconnecting

status tells you when Instagram has stopped accepting the account's token, so new posts won't arrive until the owner reconnects:

const body = await (await fetch(`https://feedframer.com/api/v1/accounts?api_key=${apiKey}`)).json();
const { status, lastFetchAt } = body.data[0].attributes;

if (status === 'invalid_token') {
  console.warn(`Instagram token is invalid. Last successful fetch: ${lastFetchAt}. Reconnect on the Feedframer Dashboard.`);
}

Profile and posts together

/api/v1/me already includes the profile fields (username, name, biography, website, profilePictureUrl, followersCount, followsCount, mediaCount). For a profile header plus a feed, one request to /me is enough:

const response = await fetch(`https://feedframer.com/api/v1/me?api_key=${apiKey}`);
const feed = await response.json();

renderProfile(feed);      // feed.username, feed.profilePictureUrl, ...
renderPosts(feed.posts);  // up to 6 posts on Free, 100 on Premium

Error responses

Errors use the JSON:API error format with the Content-Type application/vnd.api+json. There are no rate limits.

401: missing API key

{
  "errors": [
    {
      "status": "401",
      "code": "MISSING_API_KEY",
      "title": "Authentication Required",
      "detail": "An API key is required. Please provide your API key using the api_key parameter."
    }
  ]
}

401: invalid API key

Returned for an unknown key, a key that has been regenerated, or a key for a disconnected account.

{
  "errors": [
    {
      "status": "401",
      "code": "INVALID_API_KEY",
      "title": "Authentication Failed",
      "detail": "The provided API key is invalid."
    }
  ]
}

Other requests, such as a POST (405, METHOD_NOT_ALLOWED), get the same error format. See Error Handling.

Caching

In production, successful responses are cached at the edge for an hour. The cache is cleared when the account's key is regenerated or the account is disconnected, and you can clear it from the Dashboard with "Purge Cache". See Caching & Performance.

Next steps