Unable to create funding instrument at ads api sandbox



Here is a strange conversation I just had with Twitter Ads API Sandbox while trying to add a funding instrument to my sandbox account. I’m not sure what to make of it. Seems like the API is replying with errors when it shouldn’t be, but then it’s not clear if a funding source is created or not.

Tried to create a funding instrument first try…

twurl -X POST -H ads-api-sandbox.twitter.com /1/accounts/gq13q1/funding_instruments?type=CREDIT_CARD&currency=USD&start_time=2016-09-26T00:00:00Z
{"errors":[{"code":"MISSING_PARAMETER","message":"\"currency\" is a required parameter","parameter":"currency"},{"code":"MISSING_PARAMETER","message":"\"start_time\" is a required parameter","parameter":"start_time"}],...

Strange, I double checked the parameters. Trying again with the arguments in a different order…

twurl -X POST -H ads-api-sandbox.twitter.com /1/accounts/gq13q1/funding_instruments?start_time=2016-09-26T00:00:00Z&currency=USD&type=CREDIT_CARD
{"errors":[{"code":"MISSING_PARAMETER","message":"\"type\" is a required parameter","parameter":"type"},{"code":"MISSING_PARAMETER","message":"\"currency\" is a required parameter","parameter":"currency"}

Same errors. Hmm, trying the endpoint’s parameters as a quoted -d argument

twurl -X POST -H ads-api-sandbox.twitter.com -d 'start_time=2016-09-26T00:00:00Z&currency=USD&type=CREDIT_CARD' /1/accounts/gq13q1/funding_instruments
{"errors":[{"code":"INVALID","message":"An existing self-serve funding instrument was found on this account","attribute":""}],"request":{"params":{"account_id":"gq13q1","type":"CREDIT_CARD","currency":"USD","start_time":"2016-09-26T00:00:00Z"}}}

Wait, what? It got created? Let’s see, hit the GET endpoint to check

twurl -X GET -H ads-api-sandbox.twitter.com /1/accounts/gq13q1/funding_instruments | python -m json.tool
    "data": [
            "able_to_fund": true,
            "account_id": "gq13q1",
            "cancelled": false,
            "created_at": "2016-09-26T17:13:41Z",
            "credit_limit_local_micro": 500000000,
            "credit_remaining_local_micro": null,
            "currency": "USD",
            "deleted": false,
            "description": "(no payment method has been set up yet)",
            "end_time": null,
            "funded_amount_local_micro": null,
            "id": "hxm92",
            "io_header": null,
            "paused": false,
            "reasons_not_able_to_fund": [],
            "start_time": "2016-09-26T17:13:41Z",
            "type": "CREDIT_CARD",
            "updated_at": "2016-09-26T17:13:41Z"
    "data_type": "funding_instrument",
    "next_cursor": null,
    "request": {
        "params": {
            "account_id": "gq13q1"
    "total_count": 1

This is not actually a valid funding source for a sandbox account, is it?

Our app checks for no payment method has been set up yet in the description since it appears all ad accounts start with this as the default funding source.



I tried calling a POST with your same parameters, and got the same error, but it’s probably because I already had a CREDIT_CARD FI associated with my sandbox account. To eliminate the possibility of that it already had a credit card FI by default (I think it’s possible) - you might try to call -X DELETE and remove the CREDIT_CARD one, and then create it again and see if it goes smoothly.

We don’t really deal with creating and deleting funding instruments on the “production” Ads API side so generally I wouldn’t worry more about this rather than being able to process and store/display appropriate fields from various types of FIs.




Well, ok, I confirmed that deleting the funding source worked, then creating a new funding source on the sandbox worked.

The issue for us is that our code treats "able_to_fund":true, "description":"(no payment method has been set up yet)" as if the account has no valid funding source, because, for all practical purposes, it doesn’t, and from our testing, all ad accounts have this dummy credit card funding source object attached to their ad account by default upon creation. In short, this single node in the funding_instruments response tells API client applications that the ad account has not yet been funded.

I’m not a big fan of using sandbox for this, and other, reasons. It would be great if a POST to the funding_instruments endpoint in the sandbox populated randomly with one of the of the widely-known test credit card numbers.


@azPHPguru: Thanks for providing details around this. We’re exploring how we can make the responses clearer and valid funding instruments easier to identify in both the GET accounts/:account_id/funding_instruments and the POST /1/accounts/:account_id/funding_instruments (sandbox) endpoints. We appreciate you surfacing this.