-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathapiary.apib
3380 lines (2788 loc) · 179 KB
/
apiary.apib
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
FORMAT: 1A
HOST: https://platform.adstage.io/api
# AdStage API Concepts
The AdStage API allows you to pull normalized data of any granularity from many ad networks and marketing analytics tools using a unified interface.
Data sources include Google Ads, Microsoft Ads, Facebook, LinkedIn, Twitter, Instagram, Gemini, Google Analytics, and more.
AdStage's JSON APIs broadly allow developers to:
* Access data about their AdStage users, organizations, and advertising entities
* Upload custom data for use within the AdStage platform
* Pull customizable reports on advertising data in a single, normalized format
AdStage provides two API versions: V1, which is a fully stable and fully released API version, and V2, which is a fully stable version with release in progress.
Though V1 may occasionally be an appropriate choice to access certain legacy features not yet available in V2, in most cases V2 should be preferred due to its generally expanded feature set, shorter maintenance cycles, and faster performance.
When choosing a particular version, check the documentation in both versions before determining the best option.
Across endpoints and versions, AdStage APIs often refer to several key concepts, documented in this section.
The next sections group version-specific documentation for the API endpoints and common workflows.
## Date Ranges
The AdStage endpoints use date range strings to represent time periods and implement a unified date range format throughout the platform.
Date range strings can be written in two possible styles: either an absolute range such as `"2016-12-25..2016-12-31"`, or a relative range, such as `"last 30 days"` or `"this month"`.
### Explicit Date Ranges
Absolute date ranges must be formatted as `yyyy-mm-dd..yyyy-mm-dd` and refer to data for all calendar days between the two dates provided (inclusive).
Relative date ranges must be formatted according to the following chart, where `X` is an integer, and `TIME_UNIT` is one of `day`, `week`, `month`, `quarter`, or `year`:
| Relative Date String | Time Period Returned | Example (if today is `2019-06-15` in UTC) |
| -------------------- | -------------------- | ------- |
| `today` | A 24 hour timeslice starting at the most recent midnight | `"today"` == `2019-06-15T00:00:00Z - 2019-06-15T23:59:59Z` |
| `yesterday` | A 24 hour timeslice ending directly before the most recent midnight | `"yesterday"` == `2019-06-14T00:00:00Z - 2019-06-14T23:59:59Z` |
| `{{TIME_UNIT}} to date` | A timeslice from the beginning of the most recent `TIME_UNIT` ending at the most recent midnight | `"month to date"` == `2019-06-01T00:00:00Z - 2019-06-14T23:59:59Z` |
| `{{X}} {{TIME_UNITS}} to date` | A timeslice from the beginning of the `X`th most recent `TIME_UNIT` ending at the most recent midnight | `"2 months to date"` == `2019-05-01T00:00:00Z - 2019-06-14T23:59:59Z` |
| `{{TIME_UNIT}} to now` | A timeslice from the beginning of the most recent `TIME_UNIT` ending at the upcoming midnight | `"quarter to now"` == `2019-04-01T00:00:00Z - 2019-06-15T23:59:59Z` |
| `{{X}} {{TIME_UNITS}} to now` | A timeslice from the beginning of the `X`th most recent `TIME_UNIT` ending at the upcoming midnight | `"2 quarters to now"` == `2019-01-01T00:00:00Z - 2019-06-15T23:59:59Z` |
| `this {{TIME_UNIT}}` | A timeslice of 1 `TIME_UNIT` starting at the beginning of the most recent `TIME_UNIT` and ending directly before the start of the next `TIME UNIT` | `"this month"` == `2019-06-01T00:00:00Z - 2019-06-30T23:59:59Z` |
| `this {{X}} {{TIME_UNITS}}` | A timeslice of `X` `TIME_UNITS` terminating at the end of the current `TIME_UNIT` | `"this 2 months"` == `2019-05-01T00:00:00Z - 2019-06-30T23:59:59Z` |
| `last {{TIME_UNIT}}` | A timeslice of 1 `TIME_UNIT` starting at the beginning of the most recent `TIME_UNIT` and ending directly before the start of the next `TIME_UNIT` | `"last month"` == `2019-05-01T00:00:00Z - 2019-05-31T23:59:59Z` |
| `last {{X}} {{TIME_UNITS}}` | A timeslice of `X` `TIME_UNITS` terminating directly before the start of the most recent `TIME_UNIT` | `"last 2 months"` == `2019-04-01T00:00:00Z - 2019-05-31T23:59:59Z` |
Any date range string, either absolute or relative, may append a modifying prefix to shift the date range:
| Relative Date String | Time Period Returned | Example (if today is `2019-06-15` in UTC) |
| -------------------- | -------------------- | ------- |
| `previous_period {{ABSOLUTE_DATE_RANGE}}` | A timeslice the size of `ABSOLUTE_DATE_RANGE`, ending directly before the start of `ABSOLUTE_DATE_RANGE` | `"previous_period 2019-06-10..2019-06-14"` == `2019-06-05T00:00:00Z - 2019-06-09T23:59:59Z` |
| `previous_period {{RELATIVE_DATE_RANGE}}` | A timeslice the size of `RELATIVE_DATE_RANGE`, ending directly before the start of `RELATIVE_DATE_RANGE`. The size is based off of the `TIME_UNIT` of the `RELATIVE_DATE_RANGE`, so the previous period may have a different number of days if the `TIME_UNIT` varies in number of days. | `"previous_period this month"` == `2019-05-01T00:00:00Z - 2019-05-31T23:59:59Z` (note this returns a 31 day slice, while `this month` returns a 30 day slice) |
| `previous_{{TIME_UNIT}} {{ABSOLUTE_DATE_RANGE}}` | A timeslice the size of `ABSOLUTE_DATE_RANGE` but shifted back one `TIME_UNIT`. The end of `ABSOLUTE_DATE_RANGE` can be truncated if the `TIME_UNIT` varies in number of days. | `"previous_month 2019-05-11..2019-05-31"` == `2019-04-11T00:00:00Z - 2019-04-30T23:59:59Z` (note this returns a 20 day timeslice, while the original date range covered 21 days) |
| `previous_{{TIME_UNIT}} {{DATE_RANGE}}` | A timeslice the size of `DATE_RANGE` but shifted back one `TIME_UNIT`. The end of `DATE_RANGE` can be truncated if the `TIME_UNIT` varies in number of days. | `"previous_month 2019-05-11..2019-05-31"` == `2019-04-11T00:00:00Z - 2019-04-30T23:59:59Z` (note this returns a 20 day timeslice, while the original date range covered 21 days) |
### Inferred Single Day Ranges
When giving the API a single date, it will interpret the value as a date range spanning that day only:
| Single Date String | Time Period Returned | Example (if today is `2019-06-15` in UTC) |
| -------------------- | -------------------- | ------- |
| `{{ABSOLUTE_DATE}}` | A 24 hour timeslice covering the given date | `"2018-02-12"` == `2018-02-12T00:00:00Z - 2018-02-12T23:59:59Z` |
| `today` | A 24 hour timeslice starting at the most recent midnight | `"today"` == `2019-06-15T00:00:00Z - 2019-06-15T23:59:59Z` |
| `yesterday` | A 24 hour timeslice ending directly before the most recent midnight | `"yesterday"` == `2019-06-14T00:00:00Z - 2019-06-14T23:59:59Z` |
| `{{X}} {{TIME_UNITS}} ago` | A 24 hour timeslice covering the full day `X` `TIME_UNIT`s before the current date | `"2 weeks ago"` == `2019-06-01T00:00:00Z - 2019-06-01T23:59:59Z` |
## Entity IDs
AdStage has two styles of IDs that refer to a specific advertising entity (for example, a specific campaign or a specific keyword).
Though other forms of IDs may be found in some response endpoints, the newest version - the `entity_id` - should be strongly preferred, as AdStage may drop maintenance of other ID types in the future.
Often, it can be convenient to generate these ids manually without looking up the entity in the AdStage API.
To generate the entity id by hand, use the following string template:
`"/network/{network}/{entity_level}/{remote_id}"`, where:
+ The `{network}` variable must be be one of:
+ `adwords`
+ `amazon`
+ `bing_ads`
+ `facebook`
+ `gemini` (not available in cross-network reporting; see Build Report V1)
+ `google_analytics` (not available in cross-network reporting; see Build Report V1)
+ `linkedin`
+ `pinterest`
+ `quora`
+ `spotify`
+ `twitter`
+ `adstage` (with entities managed on the AdStage platform: `account_group`, `user`, `organization` and `folder`)
+ The `{entity_level}` variable must be one of:
+ `account`
+ `campaign`
+ `ad_group`
+ `ad`
+ `keyword` (including all Microsoft Ads keywords)
+ `criterion` (including all Google Ads keywords)
+ The `{remote_id}` variable must be the entity's ID on the advertising network. This can be obtained directly from the advertising network - often the entity's URL contains the `remote_id` in the relevant network's UI. Alternatively, the AdStage reporting endpoints can query `remote_id`s when a report includes the following meta fields:
+ `remote_account_id`
+ `remote_campaign_id`
+ `remote_ad_group_id`
+ `remote_ad_id`
+ `remote_keyword_id` (includes results for `criterion` ids)
## HAL JSON Resources
The AdStage API models the data it returns as discrete resources, each of which can have rich relationships to other resources.
Relationships among API resources is modeled in JSON responses with the [Hypertext Application Language (HAL) standard](https://en.wikipedia.org/wiki/Hypertext_Application_Language).
For example, an endpoint returning comprehensive data about a user may also return links to other related resources, such as the user's organization, in the JSON response.
Though a full overview of HAL is beyond the scope of this documentation, this section explains the basic principles needed to successfully interact with the rich data in most AdStage HAL responses.
HAL attempts to make JSON navigable by organizing JSON content and providing links to related content similar to how HTML organizes web content.
Just as a web page allows human users to view content and follow links to related pages, HAL allows automated systems to access JSON content and discover links to related JSON endpoints.
AdStage's HAL JSON responses are divided into four distinct sections: the main response (inside the top level JSON object), `_embedded`, `_links`, and `_forms`.
The main response contains information about the requested resource.
The `_embedded` object contains resources related to the requested resource.
The `_links` object contains URLs that define API requests for related resources or URLs for next and previous pages of the current resource.
Note that both the main request and also any embedded resources may include links specific to that resource.
The `_forms` object can optionally be provided with a link to describe various options that can be used to change or enhance the request, often with recommended submission values.
## Embedded Resources
When issuing a request to a HAL endpoint, the requested resource will typically appear inside the top-level JSON response body.
However, the response body may also contain `_embedded` objects containing information about resources related to the parent resource.
For example, when requesting information about a user in example below, the main JSON body returns data about that user, and the `_embedded` key returns information about the user's organization.
Note that any particular resource returned in the `_embedded` object may have additional HAL resources, links, and forms of its own.
**Modified HAL response from a request to a user data endpoint**
```
{
// The main response contains data about the user resource,
// which was the item requested from the endpoint
"avatar_url": "https://www.gravatar.com/avatar/123456",
"created_at": 1522185933,
"customer_status": "trialing",
"default_organization_role": "OWNER",
"email": "[email protected]",
"fetch_id": 1,
"id": "/api/users/1",
...,
// The embedded section of the response returns data about the user's organization
// because API consumers frequently wish to use data from both resources at once
"_embedded": {
"adstage:organization": {
"active_accounts_count": 9,
"is_active_customer": true,
"id": "/api/organizations/1",
"user_count": 1,
...,
// The embedded resource has HAL resources of its own,
// such as links to additional resources related to the *organization*.
"_links": {
"profile": [
{
"name": "organization",
"href": "http://platform.adstage.io/api/docs/profile/organization"
}
],
...
},
...
},
...
},
...
}
```
## Links
HAL resources may contain links to other related resources in the `_links` object.
Applications can follow the URLs in links to access these resources.
_Note that some links in the API responses may contain URLs for endpoints not documented here.
These are not maintained as stable for external users and are not supported.
Please check whether a link's endpoint is documented here before using it in your application.
Most supported HAL links for API customers are pagination related._
**Modified HAL response from a request to a user data endpoint**
```
{
// The main response contains data about the user resource,
// which was the item requested from the endpoint
"avatar_url": "https://www.gravatar.com/avatar/123456",
"created_at": 1522185933,
"customer_status": "trialing",
"default_organization_role": "OWNER",
"email": "[email protected]",
"fetch_id": 1,
"id": "/api/users/1",
...,
// The _links section of the response returns links related to the given user,
// such as a full description of the user's organization
// and lists of the user's accounts
"_links": {
"adstage:organization": {
"href": "http://platform.adstage.io/api/organizations/1"
}
// Occasionally links may include templates for URL parameters that can refine the request
"adstage:list": [
{
"templated": true,
"name": "adwords_accounts",
"href": "http://platform.adstage.io/api/users/1/list_network_accounts/adwords{?limit,offset,sort_by,order,term}"
},
{
"templated": true,
"name": "bing_ads_accounts",
"href": "http://platform.adstage.io/api/users/1/list_network_accounts/bing_ads{?limit,offset,sort_by,order,term}"
},
...
],
...
},
...
}
```
## Forms
Though forms are not officially part of the HAL standard, AdStage uses a common forms implementation in some responses.
In these responses, HAL links may also provide a related form that describes options for submitting richer data to an endpoint.
In particular, forms allow HAL to describe how to complete a non-GET request requiring complex or lengthy parameters in a JSON body.
In a few cases, forms describe a menu of allowable options for such a request and then expect the client application to determine which values to actually send from those options.
However, AdStage typically uses forms merely as more descriptive links by designating suggested values for all of the request's JSON parameters.
_Note that some forms in the API responses may contain URLs for endpoints not documented here.
These are not maintained as stable for external users and are not supported.
Check whether a form's endpoint is documented here before using it in your application.
Most supported HAL forms for API customers are pagination related._
**Modified HAL response from a reporting request**
```
{
// The main report resource
"summary": { ... },
"type": "rows",
"time": {
"end": "2019-06-26T23:59:59Z",
"start": "2019-06-26T00:00:00Z"
},
...,
// A link gives "fallback" information about the next page resource,
// but the form should be used instead since the link shows "form": true
"_links": {
"results": [],
"next_page": {
"href": "https://platform.adstage.io/api/organizations/1/report",
"method": "POST",
"form": true
}
}
// The form includes information needed to make a request to the URL
// using a rich JSON body instead of just URL parameters
"_forms": {
"next_page": {
"href": "https://platform.adstage.io/api/organizations/1/report",
// Note that the the HTTP method for a form always uses a JSON body
"method": "POST",
// Each field shows a JSON key, a JSON Schema V4 type, and a suggested value
"fields": {
// For example, this item asks users to include `"date_range": "yesterday"`
// in the JSON body for the request
"date_range": {
"type": "string",
"value": "yesterday"
},
"fields": {
"type": "array",
"value": [
"spend"
]
},
...,
"page_token": {
"type": "string",
"value": "g3QAAAADZAAFbGltaXRhGWQABm9mZnNldGEyZAABdG0AAAAGb2Zmc2V0"
}
}
}
...
}
...
}
```
## Pagination
Most AdStage API endpoints that return lists or reports have support for pagination via HAL JSON links or forms.
You can specify the number of items or rows to return with a `limit` parameter, and you can page through results by adding an `offset` parameter to subsequent requests.
For your convenience, the responses from these endpoints also include links to the next and previous pages; some endpoints may also provide links to first and last pages.
**Limit/offset pagination example:**
```
{
// The data for this page
"_embedded": { ... },
// Links to related pages
"_links": {
"next": {
"href": "https://platform.adstage.io/api/organizations/1/build_report?limit=1000&offset=3000&..."
},
"prev": {
"href": "https://platform.adstage.io/api/organizations/1/build_report?limit=1000&offset=1000&..."
},
}
}
```
Some newer endpoints may return a page token in the response link or form.
When a providing the page token as a parameter in a subsequent HTTP request, AdStage will locate the proper page of data with the page token without the need to manually manage limit and offsets.
AdStage generated tokens will always encode the proper limit and offset for the designated page, and may attempt to encode a reference to a cached page for faster performance.
If a request provides both a limit and/or offset as well as a page token, AdStage will attempt to locate the page based on the page token.
**Token pagination example:**
```
{
// The data for this page_page
"_embedded": { ... },
// Links to related pages
"_links": {
"next_page": {
"href": "https://platform.adstage.io/api/organizations/1/build_report?page_token=g3QAAAADZAAFbGltaXRhGWQABm9mZnNldGEyZAABdG0AAAAGb2Zmc2V0&..."
},
"prev_page": {
"href": "https://platform.adstage.io/api/organizations/1/build_report?page_token=g3QAAAADZAAFbGltaXRhGWQABm9mZnNldGEAZAABdG0AAAAGb2Zmc2V0&..."
}
}
}
```
## Authentication
AdStage uses HTTP header bearer tokens for API authentication.
Contact the AdStage Customer Success team at `[email protected]` or your organization's account manager to receive an authentication token.
### OAuth 2 Applications
If would like to create a application for multiple AdStage users, the AdStage API can serve as an OAuth 2 provider.
However, there is currently no self-service method to register new OAuth2 applications.
Contact the AdStage Customer Success team at `[email protected]` to have a `client_id` and `client_secret` provisioned for your application.
## Status
Keep up to date with any problems the AdStage API might be experiencing on our [status page](http://status.adstage.io/).
# Group AdStage API V1
This version of the AdStage API can be considered stable and fully released.
## Discovering Basic Organization Data [/]
The following endpoints allow developers to discover key resources belonging to the developer's organization and API user.
### Current User [GET /me{?type}]
+ Request
+ Headers
Authorization: Bearer de4dxxxxb33f
Accept: application/json
+ Attributes
+ type (string, optional) - When `lightweight`, provides a substantially more compact response by omitting several HAL resources; recommended for most use cases
+ Response 200 (application/json)
{
"first_name": "Clark",
"last_name": "Gates-George",
"email": "[email protected]",
"created_at": 1351707901,
"id": "/api/users/1",
"fetch_id": 40,
"has_linked": true,
"account_status": {
"adwords": "unimportable",
"bing_ads": "unimportable",
"facebook": "currently_importing",
"linkedin": "permanent_authentication_error",
"twitter": "currently_importing"
},
"visible_account_status": {
"adwords": "unimportable",
"bing_ads": "unimportable",
"facebook": "currently_importing",
"linkedin": "currently_importing",
"twitter": "currently_importing"
},
"_embedded": {
"adstage:organizations": [
{
"id": "/api/organizations/1",
"fetch_id": 40,
"active_accounts_count": 45,
"is_active_customer": true,
"additional_accounts_purchased": 23,
"advertiser_type": "Agency / Consultant",
"advertising_objective": "Unknown",
"billable_accounts_count": 43,
"billing_contact_email": "[email protected]",
"is_billing_error": false,
"blurb": "Connect ad accounts to the AdStage analytics dashboard and compare performance. View current key performance metrics (CPA, CPM, CTR) at a glance. Measure your advertising ROS with customizable graphs that allow you to easily gauge performance across multiple networks for any historical period. AdStage identifies your top-performing ads and keywords, which helps you determine what wording resonates well with your audience. Use that ad messaging in your sales pitch, blog posts, or website copy. ",
"company_name": "AdStage",
"customer_status": "paying",
"is_former_customer": false
}
]
}
}
### Organization [GET /organizations/{org_id}]
+ Parameters
+ org_id: 1 (number)
The fetch_id for the organization to be reported.
+ Request
+ Headers
Authorization: Bearer de4dxxxxb33f
Accept: application/json
+ Response 200 (application/json)
+ Attributes
+ id: /api/organizations/1 (string)
The path to the organization in the AdStage API.
+ fetch_id: 40 (number)
The fetch id for the organization being reported.
+ Body
{
"active_accounts_count": 45,
"is_active_customer": true,
"additional_accounts_purchased": 23,
"advertiser_type": "Agency / Consultant",
"advertising_objective": "Unknown",
"billable_accounts_count": 43,
"billing_contact_email": "[email protected]",
"is_billing_error": false,
"blurb": "Connect ad accounts to the AdStage analytics dashboard and compare performance.",
"company_name": "AdStage",
"company_url": "http://www.adstage.io",
"cumulative_monthly_spend": 12654,
"customer_status": "paying",
"fetch_id": 40
}
### Accounts [GET /users/{user_id}/list_network_accounts/all]
+ Parameters
+ `user_id`: 40 (number)
The id for the user that owns the accounts to be listed.
+ Request
+ Headers
Accept: application/json
Authorization: Bearer de4dxxxxb33f
+ Response 200
A list of accounts.
+ Attributes
+ `_links` (object)
+ next (object)
+ href (string) - A URL to get the next page of accounts
`"https://platform.adstage.io/api/users/40/list_network_accounts/all?limit=10&offset=20"`
+ prev (object)
+ href (string) - A URL to get the previous page of accounts
`"https://platform.adstage.io/api/users/40/list_network_accounts/all?limit=10&offset=0"`
+ `_embedded` (object)
+ item (array)
+ (object)
+ remote_id: "12345" (string) - the identifier assigned to this account by the ad network
+ network: "adwords" (string) - the ad network for the given account
+ name: "AdWords Account #1" (string) - the human readable name for the account
+ is_visible: true (boolean) - whether or not this account is visible
+ Body
{
"_embedded": {
"item": [
{
"remote_id": "12345",
"network": "adwords",
"network_name": "AdWords",
"name": "AdWords Account #1",
"is_visible": true,
"currency_code": "USD",
"status": "ACTIVE",
"_embedded": {},
"_forms": {
"adstage:unlink": {
"href": "https://platform.adstage.io/api/organizations/40/unlink_network_account",
"method": "PUT",
"fields": {
"network": {
"type": "hidden",
"value": "adwords"
},
"network_account_id": {
"type": "hidden",
"value": "12345"
}
}
}
},
"_links": {
"self": {
"href": "https://platform.adstage.io/api/network/adwords/accounts/12345",
"title": "AdWords Account #1"
}
}
}
]
},
"_links": {
"next": {
"href": "https://platform.adstage.io/api/users/40/list_network_accounts/all?limit=1&offset=1&networks=adwords,bing_ads,facebook,linkedin,twitter&sort_by=name&order=asc"
}
},
"counts": {
"overall": 5,
"page": 1
},
"current_page": 1,
"id": "https://platform.adstage.io/api/users/40/list_network_accounts/all?limit=1&offset=0&networks=adwords,bing_ads,facebook,linkedin,twitter&sort_by=name&order=asc",
"list_of": "item",
"page_options": {
"limit": 1,
"offset": 0
},
"page_size": 1,
"page_total": 1,
"total": 5,
"total_pages": 5
}
### Account Groups [GET /users/{user_id}/account_groups]
+ Parameters
+ user_id: 40 (number)
The id for the user that owns the account groups to be listed.
+ Request
+ Headers
Accept: application/json
Authorization: Bearer de4dxxxxb33f
+ Response 200
A list of account groups.
+ Attributes
+ _links (object)
+ next (object)
+ href (string) - A URL to get next page of account groups
`"https://platform.adstage.io/api/users/40/account_groups?limit=10&offset=20&networks=all"`
+ prev (object)
+ href (string) - A URL to get previous page of account groups
`"https://platform.adstage.io/api/users/40/account_groups?limit=10&offset=0&networks=all"`
+ _embedded (object)
+ item (array)
+ (object)
+ id: 40 (number) - the identifier assigned to this account group
+ name: "Client #1" (string) - the full human readable name for the metric
+ is_visible: true (boolean) - whether all the accounts are visible in this group
+ account_count: 5 (number) - total number of accounts in the group
+ _forms (object) - list of actions available on the account group
+ Body
{
"_embedded": {
"item": [
{
"account_count": 1,
"id": 988,
"is_visible": false,
"name": "Client 3 Marketing",
"_embedded": {},
"_forms": {
"adstage:add": {
"fields": {
"network": "string",
"network_account_id": "integer"
},
"href": "https://platform.adstage.io/api/users/40/account_groups/988/add",
"method": "POST",
"name": "account_group"
}
},
"_links": {
"adstage:add": {
"form": true,
"href": "https://platform.adstage.io/api/users/40/account_groups/988/add",
"method": "POST",
"name": "account_group"
},
"adstage:list": [
{
"href": "https://platform.adstage.io/api/users/40/account_groups/988/list_accounts{?limit,offset}",
"name": "network_accounts",
"templated": true
}
],
"self": {
"href": "/api/users/40/account_groups/988"
}
}
}
]
},
"_links": {
"next": {
"href": "https://platform.adstage.io/api/users/40/account_groups?limit=1&offset=1&networks=adwords,bing_ads,facebook,linkedin,twitter&sort_by=clicks&order=desc"
}
},
"counts": {
"overall": 5,
"page": 1
},
"current_page": 1,
"id": "https://platform.adstage.io/api/users/40/account_groups?limit=1&offset=0&networks=adwords,bing_ads,facebook,linkedin,twitter&sort_by=clicks&order=desc",
"list_of": "item",
"page_options": {
"limit": 1,
"offset": 0
},
"page_size": 1,
"page_total": 1,
"total": 5,
"total_pages": 5
}
### Folders [GET /users/{user_id}/list_folders]
+ Parameters
+ user_id: 40 (number)
The id for the user that owns the folders to be listed.
+ Request
+ Headers
Accept: application/json
Authorization: Bearer de4dxxxxb33f
+ Response 200
A list of folders.
+ Attributes
+ _links (object)
+ next (object)
+ href (string) - A URL to get next page of folders
`"https://platform.adstage.io/api/users/40/list_folders?limit=10&offset=20&networks=all"`
+ prev (object)
+ href (string) - A URL to get previous page of folders
`"https://platform.adstage.io/api/users/40/list_folders?limit=10&offset=0&networks=all"`
+ _embedded (object)
+ item (array) - list of folders
+ (object)
+ fetch_id: 40 (string) - the identifier assigned to this folder
+ id: "/api/folders/40" (string) - a uri identifier for the folder
+ name: "Folder #1" (string) - name of the folder
+ network_counts (object) - count of campaigns in folder by network
+ _forms (object) - list of actions available on the folder
+ _links (object) - list of actions and related entities to the folder
+ `adstage:network_campaign` - HAL links to adstage campaigns
+ Body
{
"_embedded": {
"item": [
{
"daily_budget_value": 0.0,
"fetch_id": "168",
"id": "/api/folders/168",
"lifetime_budget_value": 0.0,
"monthly_budget_value": 0.0,
"name": "040414 Updated",
"network_counts": {
"bing_ads": 1,
"totals": 1
},
"_forms": {
"adstage:link": {
"fields": {
"folder_id": {
"title": "Choose a folder",
"type": "adstage:folder",
"validators": [
"required"
],
"value": "/api/folders/168"
},
"network_campaign_ids": {
"title": "Choose one or more campaigns",
"type": "adstage:folder",
"validators": [
"required"
],
"value": []
}
},
"href": "https://platform.adstage.io/api/folders/168/add",
"method": "POST",
"title": "Link Campaigns to Folder"
}
},
"_links": {
"adstage:network_campaign": [
{
"data-fetch_id": 6745,
"data-id": "/api/network/bing_ads/campaigns/6745",
"data-navgroup": "search",
"data-network": "bing_ads",
"data-network_name": "Bing",
"href": "https://platform.adstage.io/api/network/bing_ads/accounts/506/campaigns/6745",
"name": "/api/network/bing_ads/campaigns/6745",
"network_account_id": "/api/network/bing_ads/accounts/506",
"network_account_name": "AdStage, Inc.",
"title": "AdStage: 040414"
}
],
"self": {
"data-fetch_id": "168",
"href": "https://platform.adstage.io/api/folders/168",
"name": "168",
"title": "040414 Updated"
}
}
}
]
},
"_links": {
"next": {
"href": "https://platform.adstage.io/api/users/40/list_folders?limit=1&offset=1&networks=adwords,bing_ads,facebook,linkedin,twitter&sort_by=clicks&order=desc"
},
"self": {
"href": "https://platform.adstage.io/api/users/40/list_folders?limit=1&access_token=57a082a0de5d9eba2d6580a3b1a7ba1876c23d0a46177f327a4289a3b272b670"
}
},
"counts": {},
"current_page": 1,
"id": "https://platform.adstage.io/api/users/40/list_folders?limit=1&offset=0&networks=adwords,bing_ads,facebook,linkedin,twitter&sort_by=clicks&order=desc",
"list_of": "item",
"page_options": {
"limit": 1,
"offset": 0
},
"page_size": 1,
"page_total": 1,
"total": 2309,
"total_pages": 2309
}
### Import Status [GET /users/{user_id}/sync_information]
+ Parameters
+ `user_id`: 40 (number)
The id for the user that owns the accounts to be check the sync status.
+ Request
+ Headers
Authorization: Bearer de4dxxxxb33f
Accept: application/json
+ Response 200 (application/json)
A list containing import status information for each linked account.
+ Attributes
+ accounts (array)
+ (object)
+ name: "Account #1" (string) - the name of the account
+ network: "adwords" (string) - the network of the account
+ `import_status` (object) - details about the import status of the account
+ code: "good" (string)
status code for the account import
* `good`: the most recent import has completed
* `currently_importing`: an import is currently running
* `permanent_authentication_error`: the account needs to be relinked due to an expired token or other authentication issue
+ `is_importing`: false (boolean) - whether or not an import is currently running for the account
+ `last_import_started`: "2018-01-01T08:30:00Z" (string) - start timestamp of the most recent import
+ `last_import_finished`: "2018-01-01T11:11:00Z" (string)
if the most recent import has completed, this timestamp represents the
end timestamp of the most recent import; if an import is currently
running, this timestamp represents the end timestamp of the previous
completed import
+ Body
{
"accounts": [
{
"name": "Account #1",
"network": "adwords",
"import_status": {
"code": "good",
"is_importing": false,
"last_import_started": "2018-01-01T08:30:00Z",
"last_import_finished": "2018-01-01T11:11:00Z",
"last_import_failed": null,
"importable": true
}
},
{
"name": "Account #2",
"network": "facebook",
"import_status": {
"code": "currently_importing",
"is_importing": true,
"last_import_started": "2018-01-01T12:00:00Z",
"last_import_finished": "2018-01-01T11:45:00Z",
"last_import_failed": null,
"importable": true
}
},
{
"name": "Account #3",
"network": "linkedin",
"import_status": {
"code": "permanent_authentication_error",
"is_importing": false,
"last_import_started": "2018-01-01T03:15:00Z",
"last_import_finished": "2018-01-01T03:20:00Z",
"last_import_failed": null,
"importable": false
}
}
]
}
## Discovering Metrics [/metric_descriptors]
Developers will often need to discover various data fields to request and interpret their desired advertising data.
The following endpoints and documentation comprise comprehensive list of permitted options for advertising data fields.
Broadly, AdStage separates these fields into two categories: metrics and meta fields.
A field is stored as a metric if an advertising network allows AdStage to request the data as a daily timeseries (for example, `"clicks"`).
Metric fields are discoverable through the Metric Descriptor resource, which provides information about how to interpret and present the field (for example, by maintaining a list of networks supporting that metric).
In contrast, a field is stored as metadata if an advertising network only allows AdStage to request a single value for the data (for example, `"title"`).
Meta fields do not have associated rich descriptor resources at this time.
**Note: In addition to checking metrics via the API, developers can refer to [this document](https://docs.google.com/spreadsheets/d/1jdlZuRMTkCjq2jf1MvH_I60-o1-mJ6SW8WPmeQ60jh8/edit?usp=sharing) that AdStage maintains as a metrics reference.**
### Meta Fields
Metadata fields are typically strings, such as an ad's `title`, though in some cases, a meta field can be of another type, such as `budget_float` - the most recent budget for the entity cast to a float.
In these cases, the casted data type is appended to the string: `budget_float` will return a float.
Because meta fields are so rarely changed, AdStage does not currently provide an API endpoint to list all meta fields on-demand.
Instead, a comprehensive list of metadata fields is provided below for convenience.
In the future, AdStage may replace this with an API endpoint for meta field discovery.
#### Entity Names
Gives the displayable names of each entity (e.g. an ad) or parent entity (e.g. the campaign owning the ad).
Often useful for filtering reports based on substrings of a name when ads are created with stable naming conventions.
| UI Display Name | API Field Name |
| ---------------------- | ----------------------- |
| Network | `network` |
| Name | `name` |
| Account Name | `account_name` |
| Campaign Name | `campaign_name` |
| Ad Group / Ad Set Name | `ad_group_name` |
| Ad Name | `ad_name` |
#### Currency Information
Gives the metadata needed to interpret currency metrics, such as spend, associated with the entity.
| UI Display Name | API Field Name |
| ---------------------- | ----------------------- |
| Currency Code | `currency_code` |
| Currency Symbol | `currency_symbol` |
#### Short IDs
Gives short form unique identifiers for each entity, matching ids generated by each remote ad network.
Prefer the more descriptive long form IDs for cases where a human may need to interpret the IDs.
For example, AdStage internally chooses the `entity_id` field as the main search field in its troubleshooting utilities.
| UI Display Name | API Field Name |
| ---------------------- | ----------------------- |
| Account ID | `remote_account_id` |
| Campaign ID | `remote_campaign_id` |
| Ad Group ID | `remote_ad_group_id` |
| Ad ID | `remote_ad_id` |
| Keyword ID | `remote_keyword_id` |
#### Account Groups and Folders IDs
Gives short form unique identifiers for entity grouping constructs managed within the AdStage UI.
Folders represent groups of campaigns, and Account Groups represent groups of accounts.
The ID of the user who created the folder is used to complete the field.
Use the `GET /me` endpoint to get the current user ID.
| UI Display Name | API Field Name | Example |
| ---------------------- | ------------------------------ | ----------------- |
| Account Group ID | `account_group_id` | |
| Account Group Name | `account_group_name` | |
| Folder Name | `folder_names.{id}` | `folder_names.40` |
| Folder ID | `folder_ids.{id}` | `folder_ids.40` |
*Note that `folder_names` and `folder_ids` will automatically infer your the requesting user's ID, though data will still be returned under the fully qualified field name (e.g. a request for `folder_names` might list results under `folder_names.40`).*
#### Long IDs
Gives long form unique identifiers for each entity, matching ids generated by each remote network.
Note that `id`, while still maintained, refers to a legacy identification strategy that AdStage no longer uses, and therefore may be deprecated in the future.
Prefer the `entity_id` variants instead for uniquely identifying ads in application logic.
| UI Display Name | API Field Name |
| ---------------------- | ------------------------------ |
| ID | `id` |
| Entity ID | `entity_id` |
| Account Entity ID | `account_entity_id` |
| Campaign Entity ID | `campaign_entity_id` |
| Ad Group Entity ID | `ad_group_entity_id` |
| Ad Entity ID | `ad_entity_id` |
| Keyword Entity ID | `keyword_entity_id` |
#### Entity Statuses
Gives the latest known status of the entity on the remote network (e.g. `COMPLETED`).
Note that the status does not necessarily correspond with the serving status.
For example, an ad marked "ACTIVE" may not be serving if its campaign is marked "INACTIVE".
| UI Display Name | API Field Name |
| ---------------------- | ------------------------------ |
| Status | `status` |
| Account Status | `account_status` |
| Campaign Status | `campaign_status` |
| Ad Group Status | `ad_group_status` |
| Ad Status | `ad_status` |
| Keyword Status | `keyword_status` |
#### Bid Information
Gives information regarding the bid on an entity.
Note that `bid_float` and `bid.value` represent the same data as a float and string respectively.
| UI Display Name | API Field Name |
| ---------------------- | ------------------------------ |
| Bid | `bid_float` |
| Pretty Bid | `bid.pretty_bid` |
| Bid Title | `bid.title` |
| Bid Subtitle | `bid.subtitle` |
| Bid Type | `bid.type` |
| Bid Value | `bid.value` |
#### Budget Information
Gives information regarding the budget for an entity.
Note that `budget_float` and `budget.value` represent the same data as a float and string respectively.