Test fixture — for the fatmira site graph. Not a real service; nothing here describes anything that exists. Build 3.
the-best-meta-ads-bench-simulator.cc

The contract

Every shape below is what the client already sends. Nothing here is a simulator convention; if a request works against this host and fails against Meta, that is a bug in this host.

Reads

GET https://graph.the-best-meta-ads-bench-simulator.cc/v26.0/act_10000000000001/campaigns
    ?fields=id,name,status,effective_status,objective,daily_budget
    &effective_status=["ACTIVE","PAUSED"]
    &limit=25
Authorization: Bearer EAAsim.default

Edges: adcreatives, ads, adsets, adspixels, advertisable_applications, campaigns, customaudiences, instagram_accounts, promote_pages, plus insights. The node must match act_[0-9]+ and nothing else — no me, no Business id, no <page-id>/feed.

Insights

GET .../act_10000000000001/insights
    ?level=campaign
    &date_preset=last_30d
    &fields=impressions,clicks,spend,ctr,cpc,actions,purchase_roas
    &filtering=[{"field":"campaign.id","operator":"IN","value":["<id>"]}]

time_range={"since":"YYYY-MM-DD","until":"YYYY-MM-DD"} beats date_preset. Every insights metric comes back as a string, integers included; actions is a list of {action_type, value}, not a dictionary and not a number.

Writes

POST   .../act_10000000000001/campaigns   name, objective, status, special_ad_categories
         → {"id": "<new id>"}          ← the id ALONE, not the created row
POST   .../<campaign_id>                     any of name, status, objective, budgets
         → {"success": true}             ← read it back if you want the new state
DELETE .../<campaign_id>
         → {"success": true}             ← takes its ad sets and ads with it

special_ad_categories is required on create — pass [] when the campaign is not in one. Omitting it is code 100 / subcode 1885183, and it is the most common first failure anybody writing against this endpoint hits. objective must be one of the six current outcomes: OUTCOME_AWARENESS, OUTCOME_TRAFFIC, OUTCOME_ENGAGEMENT, OUTCOME_LEADS, OUTCOME_APP_PROMOTION, OUTCOME_SALES. The legacy spellings (LINK_CLICKS, CONVERSIONS) are refused here because Meta refuses them on an account created today.

Errors

HTTP 400
{"error": {"message": "...", "type": "OAuthException", "code": 190,
            "error_subcode": 460, "error_user_title": "...",
            "error_user_msg": "...", "fbtrace_id": "..."}}

Read error.code, never the status. error_user_msg is present only on the errors that really carry one, so a client that reads only that field will print blanks — deliberately, because it will do the same against Meta.

Resetting

POST https://the-best-meta-ads-bench-simulator.cc/api/adsim/reset
POST https://the-best-meta-ads-bench-simulator.cc/api/adsim/reset?workspace=<name>

Use a private workspace by putting its name in the token: EAAsim.myrun. It is forked from the seed on first use; nothing has to be created first.