API documentation for Epic Foundation Inc

/portfolio

Portfolio

The characteristics of the portfolio can be found at /portfolio:

GET: /portfolio/

Parameter Value
(no parameter)  

The response is currently a single portfolio resource:

{ "portfolio": { "name": "Epic", "organizations": 30 } }

In the future if multiple portfolios are supported, this end-point will become a collection of portfolio resources.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio" button to get the list of organizations

Portfolio sector

The list of portfolio sectors can be found at /portfolio/sector:

GET: /portfolio/sector

Parameter Value
sectorId STRING OPTIONAL The ID of a portfolio sector. Defaults to no filter.

GET: /portfolio/sector/sectorId

Parameter Value
No parameter  

The response is a currently a collection of sector resources which can be empty:

{ "sectors": [ { "sector": { "sectorId": "education", "labels": [ { "label": { "sectorId": "education", "sectorName": "Education", "lang": "en" } }, { "label": { "sectorId": "education", "sectorName": "Éducation", "lang": "fr" } } ], "logoUri": "/static/portfolio/logo/education.svg" } }, {...}, ... ] }

The logoUri is presented in the context of the API root so if the logo is included on a web page, the URL should be:

<img src='https://api.epic.foundation/static/portfolio/logo/education.svg />

The logoUri will normally be a 100x100 SVG image.

The labels collection presents the name of the portfolio in the various supported.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Sector" button to get the list of organizations

Portfolio organizations

The list of portfolio organizations can be found at /portfolio/organization:

GET: /portfolio/organization/

Parameter Value
name STRING OPTIONAL A fragment of the name of the organization. This fragment will be wildcarded to find any organization whose name contains the fragment. Defaults to no filter.
joined INT OPTIONAL The year the organization joined the portfolio. Only one year can be provided. Current valid values are 2015, 2016, 2017 or 2018. Defaults to no filter.
lim INT OPTIONAL The maximum number of organizations returned. Can be absent or greater than 0. Defaults to unlimited.
offset INT OPTIONAL The rank of the first organization returned. Will be ignored if lim is not present. Can be absent or greater than or equal to 0. Defaults to 0. NOTE: If you set an offset greater than the size of your result set, nothing will be returned. So if you specify the organization ID using the id parameter below, make sure not to set a limit or offset.
id STRING OPTIONAL The ID of an organization. Canonically equivalent to calling /portfolio/organization/id. Can be absent or with the exact ID of a portfolio organization. NOTE: the presentation of the (single) organization resource will be the same, i.e. it will be a collection of organizations with just one organization in it.

GET: /portfolio/organization/organizationId

Parameter Value
No parameter  

The response is a currently a collection of organization resources which can be empty:

{ "organizations": [ { "organization": { "id": "agir-pour-l-ecole", "name": "Agir pour l’École", "since": 2017, "founded": 1999, "website": "http://www.agirpourlecole.org/", "logoUri": "/static/portfolio/logo/agir-pour-l-ecole.png", "visualUri": "/static/portfolio/visual/agir-pour-l-ecole.jpg" } }, {...}, ... ] }

The logoUri and visualUri are presented in the context of the API root so if the logo is included on a web page, the URL should be:

<img src='https://api.epic.foundation/static/portfolio/logo/agir-pour-l-ecole.png />

The logoUri will normally be a 100x100 pixels image. The visualUri will normally be a 1200x600 pixels image that can be used to illustrate the organization. Those dimensions are not expected to change outside of a new API version.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Organization" button to get the list of organizations. Use the fields below to add filters. Filter restrictions add up. The name filter can contain multiple words (or fragments thereof) which are all required. Check the checkbox below to dynamically evaluate the request as you type in the names filter field.

Portfolio Organization Sector

The details of the sectors of a portfolio organization can be found at /portfolio/organization/sector:

GET: /portfolio/organization/sector

Parameter Value
id STRING REQUIRED The ID of a portfolio organization. Is canonically equivalent to calling /portfolio/organization/organizationId/sector

GET: /portfolio/organization/organizationId/sector

Parameter Value
No parameter See above

The response is a currently a collection of sector resources as described in /portfolio/sector.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Organization Sector" button to get the list of organizations

Portfolio Organization Introduction

The introduction for a given portfolio organization can be found at /portfolio/organization/introduction:

GET: /portfolio/organization/introduction

Parameter Value
id STRING REQUIRED The ID of a portfolio organization. Is canonically equivalent to calling /portfolio/organization/organizationId/introduction

GET: /portfolio/organization/organizationId/introduction

Parameter Value
lang STRING OPTIONAL The ID of a requested language. Should be one of en or fr (case insensitive).

The response is a collection of introduction resources (which can be empty):

{ "introductions": [ { "introduction": { "id": "sport-dans-la-ville", "lang": "en", "text": "Sport dans la Ville (SDLV) helps at-risk girls and boys in..." } }, { "introduction": { "id": "sport-dans-la-ville", "lang": "fr", "text": "Sport dans la Ville (SDLV) aide des filles et garçons vulnérables ..." } } ] }

NOTE: all end-points that provide text return all languages by default. The idea is to provide all the information for any client to produce DOM elements like:

<p lang='en'>English version</p> <p lang='fr'>Version française</p>

which can then be shown based on the preferred language:

$("*[lang='fr']").hide(); $("*[lang='en']").show();

It is possible to request only one language, but the formalism of the response will be the same.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Organization introduction" button to get the introduction for a given organization

Portfolio Organization Summary

The (usually 1-sentence) summary for a given portfolio organization can be found at /portfolio/organization/summary:

GET: /portfolio/organization/summary

Parameter Value
id STRING REQUIRED The ID of a portfolio organization. Is canonically equivalent to calling /portfolio/organization/organizationId/summary

GET: /portfolio/organization/organizationId/summary

Parameter Value
lang STRING OPTIONAL The ID of a requested language. Should be one of en or fr (case insensitive).

The response is a collection of summary resources (which can be empty):

{ "summaries": [ { "summary": { "id": "ali-forney-center", "lang": "en", "text": "The nation's most comprehensive housing program for homeless LGTBQ youth.", "highlight": "homeless LGTBQ youth." } }, { "summary": { "id": "ali-forney-center", "lang": "fr", "text": "Le programme d'hébergement pour jeunes sans-abris LGBTQ le plus complet du pays.", "highlight": "le plus complet du pays." } } ] }

NOTE: all end-points that provide text return all languages by default. The idea is to provide all the information for any client to produce DOM elements like:

<p lang='en'>English version</p> <p lang='fr'>Version française</p>

which can then be shown based on the preferred language:

$("*[lang='fr']").hide(); $("*[lang='en']").show();

It is possible to request only one language, but the formalism of the response will be the same.

The highlight element is intended to identify the most important chunk of information to allow for the systematic rendering of it in a magnified way, such as uppercase, bold, color highlight etc, using regular expression.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Organization Summary" button to get the introduction for a given organization

Portfolio Organization Programs

The list of key programs for a given portfolio organization can be found at /portfolio/organization/program:

GET: /portfolio/organization/program

GET: /portfolio/organization/organizationId/program

Parameter Value
id STRING CONDITIONAL The ID of a portfolio organization. Is canonically equivalent to calling /portfolio/organization/organizationId/program. Only required if not present in the URI
lim INT OPTIONAL The maximum number of organization challenges returned. Can be absent or greater than 0. Defaults to unlimited. NOTE: the limit applies collectively to all languages.
offset INT OPTIONAL The rank of the first organization program returned. Will be ignored if lim is not present. Can be absent or greater than or equal to 0. Defaults to 0. NOTE: If you set an offset greater than the size of your result set, nothing will be returned.
lang STRING OPTIONAL The ID of a requested language. Should be one of en or fr (case insensitive). Defaults to all languages

The response is a collection of programs resources (which can be empty):

{ "programs": [ { "programs": { "id": "ali-forney-center", "lang": "en", "programTitle": "Prevention, outreach & treatment for HIV/AIDS ", "programDescription": "The Ali Forney Center provides LGBTQ youth with a wide range of healthcare services including testing and treatment for HIV/AIDS, Hepatitis C and Sexually Transmitted Infections, Hormone Replacement Therapy and contraceptives. At least 20% of AFC's clients are tested HIV positive and receive treatment." } }, { "summary": { "id": "ali-forney-center", "lang": "fr", "programTitle": "Prévention, aide sociale et traitement du VIH/SIDA ", "programDescription": "L’Ali Forney Center fournit aux jeunes LGBTQ tout un ensemble de services de santé y compris des tests et traitement pour le VIH/SIDA, l’hépatite C et les IST, ainsi que des traitements hormonaux de substitution et des contraceptifs. Au moins 20 % des clients d’AFC sont testés positifs au VIH et reçoivent un traitement." } } ] }

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Organization Programs" button to get the introduction for a given organization

Portfolio Organization Challenge

The (usually 1-sentence) challenge for a given portfolio organization can be found at /portfolio/organization/challenge:

GET: /portfolio/organization/challenge

Parameter Value
id STRING REQUIRED The ID of a portfolio organization. Is canonically equivalent to calling /portfolio/organization/organizationId/challenge
lim INT OPTIONAL The maximum number of organization challenges returned. Can be absent or greater than 0. Defaults to unlimited. NOTE: the limit applies collectively to all languages.
offset INT OPTIONAL The rank of the first organization returned. Will be ignored if lim is not present. Can be absent or greater than or equal to 0. Defaults to 0. NOTE: If you set an offset greater than the size of your result set, nothing will be returned.
lang STRING OPTIONAL The ID of a requested language. Should be one of en or fr (case insensitive).

GET: /portfolio/organization/organizationId/challenge

The response is a collection of challenge resources (which can be empty):

{ "challenges": [ { "challenge": { "id": 1, "lang": "fr", "text": "Aux États-Unis, seulement 38% des étudiants qui quittent le lycée ont les savoirs requis pour suivre dans l'enseignement supérieur", "highlight": "38%" } }, { "challenge": { "id": 2, "lang": "fr", "text": "1 sur 4 parmi les étudiants de première année doivent s'inscrire à des cours de mise à niveau", "highlight": "1 sur 4" } } ] }

NOTE: all end-points that provide text return all languages by default. The idea is to provide all the information for any client to produce DOM elements like:

<p lang='en'>English version</p> <p lang='fr'>Version française</p>

which can then be shown based on the preferred language:

$("*[lang='fr']").hide(); $("*[lang='en']").show();

It is possible to request only one language, but the formalism of the response will be the same.

The highlight element is intended to identify the most important chunk of information to allow for the systematic rendering of it in a magnified way, such as uppercase, bold, color highlight etc, using regular expression.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Organization Challenge" button to get the introduction for a given organization

Portfolio Organization Datasets

The annual datasets for a given portfolio organization can be found at /portfolio/organization/datasets:

GET: /portfolio/organization/datasets

Parameter Value
id STRING REQUIRED The ID of a portfolio organization. Is canonically equivalent to calling /portfolio/organization/organizationId/datasets

GET: /portfolio/organization/organizationId/datasets

Parameter Value
year int OPTIONAL The year of the requested snapshot.

The response is a collection of dataset resources (which can be empty):

{ "datasets": [ { "dataset": { "id": "commonlit", "year": 2018, "beneficiaries": 0, "ageFrom": "10", "ageTo": "18", "staffHeadcount": 20, "budget": 3100000, "budgetCurrency": "USD", "vrVideoUrl": "" } } ] }

NOTE: all end-points that provide text return all languages by default. The idea is to provide all the information for any client to produce DOM elements like:

<p lang='en'>English version</p> <p lang='fr'>Version française</p>

which can then be shown based on the preferred language:

$("*[lang='fr']").hide(); $("*[lang='en']").show();

It is possible to request only one language, but the formalism of the response will be the same.

The highlight element is intended to identify the most important chunk of information to allow for the systematic rendering of it in a magnified way, such as uppercase, bold, color highlight etc, using regular expression.

Example

Make sure your have run the /oauth2/get-token first to have a valid token.

Click on the "Get Portfolio Organization Summary" button to get the introduction for a given organization

Full Example

Click on the button below to load a simple view of all the organizations in the portfolio using the API. The full code (in javascript) is displayed below. NOTE: we do not recommend using client-side javascript to build your client as it will expose your API keys. Server-side calls to the API are more appropriate.

  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
<div id='full-example-result'></div>
        <script>
        $(document).ready(  function() {

          function getOrganizations ( tokenData )
          {
            //get the list of organizations
            $.ajax({
               url:    "https://api.epic.foundation/portfolio/organization",
               dataType: "json",
               method:   "GET",
               access_token: tokenData.access_token,
               data:     {
                             access_token:   tokenData.access_token
                         },
               cache:    false,
               success: function( portfolioData, status, request )
                        {
                            if (    ( typeof portfolioData != "undefined")
                                 && ( typeof portfolioData.organizations != "undefined")
                               )
                            {
                               $.each( portfolioData.organizations , getOrganizationsClosureFn ( this.access_token ));
                            }
                        }
           });
          }

          // returns an iterating function to build each organization block
          // with the access_token present in the scope for further subsequent callbacks
          function getOrganizationsClosureFn( access_token )
          {
            var accessToken = access_token;
            return function ( index , element )
            {
                BuildOrganization ( element , accessToken );
            }
          }

          // Builds the organization block
          function BuildOrganization ( organizationJsonElement , accessToken )
          {
            var id = organizationJsonElement.organization.id;
            var org = $("<div class='org' id='" + id + "'></div>");
            org.append("<h3>" + organizationJsonElement.organization.name + "</h3>");
            org.append("<div class='data'></div>");
            org.children(".data").first().append("<span class='joined'>Epic since " +  organizationJsonElement.organization.since  + "</span>");
            org.children(".data").first().append("<span class='founded'>Founded in " +  organizationJsonElement.organization.founded  + "</span>");
            org.append("<div class='sectors'></div>");
            org.append("<span class='logo'><a href='" + organizationJsonElement.organization.website + "' target='_new' ><img src='" + organizationJsonElement.organization.logoUri + "' alt='" + organizationJsonElement.organization.name + "'/></a></span>");
            org.append("<div class='splash'><img src='" + organizationJsonElement.organization.visualUri + "' alt='" + organizationJsonElement.organization.name + "'/></div>");
            $("#full-example-result").append( org );
            // enrich with the sectors
            $.ajax({
               url:    "https://api.epic.foundation/portfolio/organization/" + id  + "/sector",
               dataType: "json",
               method:   "GET",
               id:       id,
               data:     {
                             access_token:   accessToken
                         },
               cache:    false,
               success: function( sectorsJsonElement , status, request )
                        {
                            if (    (typeof sectorsJsonElement != "undefined")
                                 && (typeof sectorsJsonElement.sectors != "undefined")
                                 && (Object.keys(sectorsJsonElement.sectors).length > 0)
                               )
                            {
                               $.each( sectorsJsonElement.sectors , AddOrganizationSectorsClosureFn( this.id ));
                            }
                        }
           });

          }

          // returns an iterating function to build the sectors for the org block
          // with the org id present in the scope for subsequent insertion into
          // the proper DOM element
          function AddOrganizationSectorsClosureFn( id )
          {
            var orgId = id;
            return function ( index , element )
            {
               //add the list of sectors to organization
               $.each( element.sector , BuildSectorBlockClosureFn ( element.sector , orgId ));
            }
          }

          // returns an iterating function to get the labels for the sectors
          // with the org id and the sector element in context
          function BuildSectorBlockClosureFn (sector , orgId )
          {
             var id            = orgId;
             var sectorElement = sector;
             var sectorIdDOM   = id + "_" + sectorElement.sectorId;
             var sectorDOM = $("<span class='sector' id='" + id + "_" + sectorElement.sectorId  + "'><img src='" + sectorElement.logoUri + "' /></span>");
             // Add the sector to the DOM
             $("#" + id + " .sectors"  ).append( sectorDOM );

             // add the labels
             if ( Object.keys(sectorElement.labels).length > 0)
             {
                 $.each( sectorElement.labels , AddSectorLabelClosureFn( sectorElement , id , sectorIdDOM ));
             }
             return function ( index , element )
             {
                 //add a label for reach language
                 //$.each( sector.labels , AddSectorLabelClosureFn( sectorElement , id , sectorIdDOM ));
             }
          }

          // returns an iterative function to loop throuh all the sector lang labels
          // with the org ID and the sector element in context for subsequent insertion
          // into the DOM
          function AddSectorLabelClosureFn ( sectorElement , orgId , sectorIdDOM )
          {
            var sector    = sectorElement ;
            var id        = orgId;
            var domTarget = sectorIdDOM;

            return function ( index , element )
            {
                //add a label for reach language
                $("#" + domTarget ).append("<label lang='" +  element.label.lang + "'>" + element.label.sectorName + "</label>");
            }
          }


          // Button trigger
          $("#full-example").click( function ( event ) {
                //empty the result
                $("#full-example-result").html("");
                //add styles
                $("#full-example-result").append("<style> .data { display: flex; justify-content: space-between; } #full-example-result { background-color: #e4e3dd; display: flex; flex-wrap: wrap; justify-content: space-between; } .org { flex-basis: calc(50% - 30px); margin: 5px; padding: 0px; background-color: rgba(41, 171, 226, 0.38); position: relative; } .org h3 { color: #2da6df; background-color: rgb(0,49,66); padding: 5px 10px; margin: 0;} .org .joined, .org .founded { font-weight: bold; font-size: 0.9em; background-color: #efa508; padding: 5px 7px; } .org .logo img { width: 65%; height: 65%; } .org .logo a { width: 100px; display: block; text-align: center;} .org .logo { z-index:50; width: 100px; height: 100px; position: absolute; bottom: 10px; left: 10px; border-radius: 100px; justify-content: center; display: flex; background-color: white; align-content: center; align-items: center;} .org .splash img { width: 100%; height: auto; } .sectors {  display: flex; justify-content: flex-end; position: absolute; bottom: 0; right: 0; z-index: 30; background-color: white; opacity: 0.8; border-top-left-radius: 14px; } .sector { flex-basis: 30px; flex-grow: 0; flex-shrink: 0; margin: 5px; } .sector label {  font-size: 0.6em; display: none; background-color: rgb(0,49,66); color: white; font-weight: bold; padding: 5px 8px;}  .sector img { width: 30px; height: 30px; }</style>");

                //Get a fresh token
                $.ajax({
                    url:    "https://api.epic.foundation/oauth2/get-token",
                    dataType: "json",
                    method:   "POST",
                    data:     {
                                  grant_type:    "client_credentials",
                                  client_id:     "testclient",
                                  client_secret: "testpass"
                              },
                    cache:    false,
                    success: function( tokenData, status, request)
                             {
                                 if ( (typeof tokenData != "undefined") && ( typeof tokenData.access_token != "undefined"))
                                 {
                                     getOrganizations ( tokenData );
                                 };
                             }
                });

                event.stopPropagation();
            });
        });
        </script>