Instagram Reels API audio: AAC, 48 kHz max, mono or stereo

Meta's Reel spec asks for AAC audio, a sample rate of 48 kHz at most, 1 or 2 channels and 128 kbps. Check those fields with a Sume video inspect probe first.

4 min readSume
All posts

For an Instagram Reel through the API, Meta's IG User Media reference lists the audio as AAC, 48 kHz sample rate maximum, 1 or 2 channels (mono or stereo), with an audio bitrate of 128 kbps (read 2026-10-02). Sume's video inspect probe returns audio_codec, audio_channels, audio_sample_rate and has_audio, which covers three of those four items before you create a container.

What does the Reel audio spec say?

The audio line sits next to the video requirements in the Reel specifications. Stories use the same audio line.

Reel audio items on Meta's IG User Media page, with the Sume probe field that shows each (read 2026-10-02)
Meta itemValueSume probe field
Audio codecAACaudio_codec
Sample rate48 kHz maximumaudio_sample_rate
Channels1 or 2audio_channels
Audio bitrate128 kbpsNot in the probe

Which of these can I check with Sume?

Codec, channel count and sample rate. The probe schema has no audio bitrate field, so that item stays unchecked. Probe and stills are unbilled; with frames: false you get the probe alone.

A clip without sound reports has_audio: false and a null codec. The page does not say whether a Reel must have audio, so a silent clip is something to test, not to assume.

import hashlib, os, time, requests
BASE = "https://api.sume.com"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}

def probe(video_url):
    key = "probe-" + hashlib.sha256(video_url.encode()).hexdigest()[:24]
    r = requests.post(f"{BASE}/v1/video-inspect", headers={**H, "Idempotency-Key": key},
                      json={"video_url": video_url, "frames": False}, timeout=60)
    r.raise_for_status()
    rid = r.json()["data"]["video_inspect_id"]
    while True:
        d = requests.get(f"{BASE}/v1/video-inspect/{rid}", headers=H, timeout=30).json()["data"]
        if d["resource_status"] == "ready":
            return d["probe"]
        if d["resource_status"] in ("failed", "canceled"):
            raise RuntimeError(d["error"])
        time.sleep(2)

p = probe("https://media.sume.com/artifacts/artf_demo/talk.mp4")
problems = []
if not p["has_audio"]:
    print("no audio track")
else:
    if (p["audio_codec"] or "").lower() != "aac": problems.append(f"codec {p['audio_codec']}")
    if (p["audio_sample_rate"] or 0) > 48000: problems.append(f"{p['audio_sample_rate']} Hz")
    if p["audio_channels"] not in (1, 2): problems.append(f"{p['audio_channels']} channels")
print(problems or "audio fields within the listed limits")

What if the audio is outside the limits?

Video trim with precision: exact re-encodes the clip and, per its docs, remuxes kept audio as AAC. That fixes a codec mismatch. The docs do not list a sample-rate or channel option on trim, so a 96 kHz or 6-channel source needs another route; regenerate the audio at a supported shape instead.

Trim's precision: keyframe is a stream copy, so it keeps the source audio unchanged.

What should I do?

Probe every file, fail on the three checkable fields, and keep the 128 kbps item as a manual check on a sample. The Facebook Reels audio spec is covered in its own post; this one is Instagram only.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume