Best Practices
This is a best practices guide around using the Instagram API so that you don't get rate limited or banned.
Use a Proxy
If you're getting errors like this
- "The username you entered doesn't appear to belong to an account. Please check your username and try again."
Or you notice that Instagram is sending you emails about a suspicious login attempt, you should consider using a proxy. You are getting rate limited by Instagram or they are suspicious of your location.
You should have an IP address that you use consistently per user when making API requests. This will be less suspicious than using a different IP address every time you make a request.
From our experience, here are safe limits we've seen for various actions: - using 10 accounts per IP address - publishing 4-16 posts for each account - publishing 24-48 stories
We recommend using the SOAX proxy service. Here's an example of using it with aiograpi
from aiograpi import Client
cl = Client()
before_ip = await cl._send_public_request("https://api.ipify.org/")
cl.set_proxy("http://<api_key>:wifi;ca;;;toronto@proxy.soax.com:9137")
after_ip = await cl._send_public_request("https://api.ipify.org/")
print(f"Before: {before_ip}")
print(f"After: {after_ip}")
Add Delays
It's recommended you try to mimic the behavior of a real user. This means you should add delays between requests. The delays should be random and not too long.
The following is a good example of how to add delays between requests.
from aiograpi import Client
cl = Client()
# adds a random delay between 1 and 3 seconds after each request
cl.delay_range = [1, 3]
Use Sessions
When using .login() you will login and create a new session with Instagram every time.
This is suspicious for Instagram.
For example, when you use your mobile device, you login to Instagram once
and then you can use it for a long time without logging in again. This is because Instagram stores
your session on your device and you can use it to login to Instagram without entering your username
and password again.
To mimic this behavior, you can use the .login() method once to create a session and then store that session using .dump_settings() and then load it again using .load_settings().
The first time you run your script
from aiograpi import Client
async def main():
cl = Client()
await cl.login(USERNAME, PASSWORD)
cl.dump_settings("session.json")
And the next time
from aiograpi import Client
async def main():
cl = Client()
cl.load_settings("session.json")
await cl.login(USERNAME, PASSWORD)
cl.dump_settings("session.json")
login() validates the loaded session before reusing it. When Instagram
returns login_required, aiograpi clears the rejected authorization and logs
in again with the supplied credentials. Other errors still propagate so rate
limits, challenges, and network failures are not mistaken for an expired
session. Save the settings again in case the session was refreshed.
Putting this all together, you can write a reusable login helper like this:
from aiograpi import Client
from pathlib import Path
async def login_user():
"""Login with a saved session and refresh it only when required."""
session_file = Path("session.json")
cl = Client()
if session_file.exists():
cl.load_settings(session_file)
await cl.login(USERNAME, PASSWORD)
cl.dump_settings(session_file)
return cl