Quick Start

Last updated: August 23rd, 2017

Introduction

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Changes

This is a version one. Advance notification of breaking changes will be available in this document and will be sent by email to our developer mailing list.

Authentication

Most API calls are using Token for verifying the request. You need to be an authorized user to obtain your API Token Key for more information and token request contact Pharmacy Reporting Tool Administrators.

Requests

The base URL of the API is http://htools-tz-pharmacy-reporting-tool-api.dokku-1.codefortanzania.org/api/ to access and send your requests.

JSON Bodies

All POST, PUT, PATCH requests are JSON encoded and must have have content type of application/json, or the API will return a 415 Unsupported Media Type status code.

$ curl http://htools-tz-pharmacy-reporting-tool-api.dokku-1.codefortanzania.org/api/pharmacies/23 \
-H 'Content-Type: application/json' \
-d '{"registration_number":"543abc"}'

HTTP Verbs

The API uses the standard HTTP verbs to indicate intent of a request:

  • GET - To retrieve a resource or a collection of resources
  • POST - To create a resource
  • PATCH - To modify a resource
  • PUT - To set a resource
  • DELETE - To delete a resource

Limited HTTP Clients

If you are using an HTTP client that doesn't support PUT, PATCH or DELETE requests, send a POST request with an X-HTTP-Method-Override header specifying the desired verb.

$ curl http://htools-tz-pharmacy-reporting-tool-api.dokku-1.codefortanzania.org/api/pharmacies/23 \
-X POST \
-H "X-HTTP-Method-Override: DELETE"

Responses

All response bodies are JSON encoded.

A single resource is represented as a JSON object:

{
  "field1": "value",
  "field2": true,
  "field3": []
}

A collection of resources is represented as a JSON array of objects:

[
  {
    "field1": "value",
    "field2": true,
    "field3": []
  },
  {
    "field1": "another value",
    "field2": false,
    "field3": []
  }
]

Timestamps are in UTC and formatted as ISO8601.

Unset fields will be represented as a null instead of not being present. If the field is an array, it will be represented as an empty array - ie [].

HTTP Status Codes

We use HTTP status codes to indicate success or failure of a request.

Success codes:

  • 200 OK - Request succeeded. Response included
  • 201 Created - Resource created. URL to new resource in Location header
  • 204 No Content - Request succeeded, but no response body

Error codes:

  • 400 Bad Request - Could not parse request
  • 401 Unauthorized - No authentication credentials provided or authentication failed
  • 403 Forbidden - Authenticated user does not have access
  • 404 Not Found - Resource not found
  • 415 Unsupported Media Type - POST/PUT/PATCH request occurred without a application/json content type
  • 422 Unprocessable Entry - A request to modify or create a resource failed due to a validation error
  • 429 Too Many Requests - Request rejected due to rate limiting
  • 500, 501, 502, 503, etc - An internal server error occured

Errors

All 400 series errors (400, 401, 403, etc) will be returned with a JSON object in the body and a application/json content type.

{
  "message": "Not Found"
}

500 series error codes (500, 501, 502, etc) do not return JSON bodies.

Validation Errors

In case of validation errors on a POST/PUT/PATCH request, a 422 Unprocessable Entry status code will be returned. The JSON response body will include an array of error messages.

{
  "message": "Validation Failed",
  "errors": [
    {
      "message": "Field is not valid"
    },
    {
      "message": "OtherField is already used"
    }
  ]
}

Column Filtering

All responses from the API can limit fields to only the fields you need. Just pass in a columns query parameter with a comma separated list of fields you need

For example:

GET /api/pharmacies?columns=registration_number,pharmacist

Would have the following response body:

[
  {
    "registration_number": "543abc",
    "pharmacist:": "John"
  },
  {
    "registration_number": "543add",
    "pharmacist:": "Bob"
  }
]

Pagination

Requests for collections can return between 0 and 100 results, controlled using the limit and page query parameters. All end points are limited to 10 results by default.

GET /api/pharmacies?lmit=5&page=2

Not all endpoints support pagination. If they do, it will be mentioned in their documentation.

Sorting

Some endpoints offer result sorting, triggered using the order_by query parameter. You can specify descending sort by postpending desc to a field. Not all fields can be sorted on. The endpoint documentation will list supported sort options.

GET /api/pharmacies?order_by=date_registered,desc

Searching

Some endpoints offer result searching, triggered at the query parameter by entering the column name followed by the search query. Not all fields can be sorted on. The endpoint documentation will list supported sort options.

GET /api/pharmacies?registration_number=ab453ciu

Pharmacies

All requests are tracked as pharmacies.

Field Type Notes
id int Associated pharmacy
registration_number string Pharmacy registration number
name string Pharmacy name
pharmacist string Pharmacist name
address string Pharmacy address
location string Pharmacy location
ward string Pharmacy ward
district string Pharmacy district
region string Pharmacy region
date_registered string The date when pharmacy was registered by TFDA
created_at timestamp Time when the pharmacy was added.
updated_at timestamp Time when the pharmacy details were last updated

Listing pharmacies

GET /api/pharmacies

Query Parameter Notes
api_token NOT REQUIRED
page Page number, starting from 1
limit Any integer between 0 and 100, inclusive
order_by See Sorting
columns See Column Filtering

Sample Request

GET /api/pharmacies?limit=1&order_by=date_registered,asc

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 564
Content-Type: application/json; charset=utf-8


{ "pharmacies": [ { "id": 11, "registration_number": "222XX", "name": "Pharmacy1XX", "pharmacist": "DaktariXX", "address": "33 MlandiziXX", "location": "MlandiziXX", "ward": "Kibaha VijijiniXX", "district": "KibahaXX", "region": "PwaniXX", "date_registered": "13 August 2014XX", "created_at": "2017-08-16 07:54:34", "updated_at": "2017-08-16 07:54:34" } ] }

Getting a single pharmacy

GET /api/pharmacies/id

Query Parameter Notes
api_token NOT REQUIRED

Sample Request

GET /api/pharmacies/11

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 272
Content-Type: application/json; charset=utf-8


{ "pharmacy": { "id": 11, "registration_number": "222XX", "name": "Pharmacy1XX", "pharmacist": "DaktariXX", "address": "33 MlandiziXX", "location": "MlandiziXX", "ward": "Kibaha VijijiniXX", "district": "KibahaXX", "region": "PwaniXX", "date_registered": "13 August 2014XX", "created_at": "2017-08-16 07:54:34", "updated_at": "2017-08-16 07:54:34" } }

Updating pharmacy

PUT /api/pharmacies/id?api_token={YOUR_API_TOKEN_KEY}

Field Required Notes
pharmacist no Set of characters representing pharmacist name
location no Set of characters representing pharmacy location
name no Set of characters representing pharmacy name
address no Set of characters representing pharmacy address
registration_number no Set of characters representing pharmacy registration number
ward no Set of characters representing pharmacy ward
district no Set of characters representing pharmacy district
region no Set of characters representing pharmacy region

Sample Request


PUT /api/pharmacies/11?api_token={YOUR_API_TOKEN_KEY}
Content-Type: application/json;


{ "registration_number":"222YY", "name":"Pharmacy1YY", "pharmacist":"DaktariYY", "address":"33 MlandiziYY", "location":"MlandiziYY" }

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 180
Content-Type: application/json; charset=utf-8


{ "pharmacy": { "id": 11, "registration_number": "222YY", "name": "Pharmacy1YY", "pharmacist": "DaktariYY", "address": "33 MlandiziYY", "location": "MlandiziYY", "ward": "Kibaha VijijiniXX", "district": "KibahaXX", "region": "PwaniXX", "date_registered": "13 August 2014XX", "created_at": "2017-08-16 07:54:34", "updated_at": "2017-08-16 11:54:18" } }

Creating a new pharmacy

POST /api/pharmacies?api_token={YOUR_API_TOKEN_KEY}

Field Required Notes
pharmacist yes Set of characters representing pharmacist name
location yes Set of characters representing pharmacy location
name yes Set of characters representing pharmacy name
address yes Set of characters representing pharmacy address
registration_number yes Set of characters representing pharmacy registration number
ward yes Set of characters representing pharmacy ward
district yes Set of characters representing pharmacy district
region yes Set of characters representing pharmacy region

Sample Request


POST /api/pharmacies?api_token={YOUR_API_TOKEN_KEY}
Content-Type: application/json;


{ "registration_number":"222XX", "name":"Pharmacy1XX", "pharmacist":"DaktariXX", "address":"33 MlandiziXX", "location":"MlandiziXX", "ward":"Kibaha VijijiniXX", "district":"KibahaXX", "region":"PwaniXX", "date_registered":"13 August 2014XX" }

It's response


Status Code: 201 Created
Connection: Keep-Alive
Content-Length: 467
Content-Type: application/json; charset=utf-8


{ "pharmacy": { "registration_number": "222XX", "name": "Pharmacy1XX", "pharmacist": "DaktariXX", "address": "33 MlandiziXX", "location": "MlandiziXX", "ward": "Kibaha VijijiniXX", "district": "KibahaXX", "region": "PwaniXX", "date_registered": "13 August 2014XX", "updated_at": "2017-08-16 12:16:45", "created_at": "2017-08-16 12:16:45", "id": 12 } }

Removing pharmacy

DELETE /api/pharmacies/id?api_token={YOUR_API_TOKEN_KEY}

Sample Request


DELETE /api/pharmacies/11?api_token={YOUR_API_TOKEN_KEY}

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 643
Content-Type: application/json; charset=utf-8


{ }

Reports

All requests are tracked as reports.

Field Type Notes
id int Associated report
gender int Gender of the reporter
location string Location of the reporter
message text Reported problem
created_at timestamp Time when the report was added
updated_at timestamp Time when the report details were last updated

Listing reports

GET /api/reports?api_token={YOUR_TOKEN_KEY}

Query Parameter Notes
api_token Your API TOKEN KEY
page Page number, starting from 1
limit Any integer between 0 and 100, inclusive
order_by See Sorting
columns See Column Filtering

Sample Request

GET /api/reports?limit=1&api_token={YOUR_API_TOKEN_KEY}

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 908
Content-Type: application/json; charset=utf-8


{ "reports": [ { "id": 10, "gender": "Female", "location": "Schaefermouth", "message": "Duchess, 'as pigs have to beat them off, and had just succeeded in getting its body tucked away, comfortably enough, under her arm, with its mouth and yawned once or twice, half hoping that they.", "created_at": "2017-08-16 07:44:01", "updated_at": "2017-08-16 07:44:01" } ] }

Getting a single report

GET /api/reports/id?api_token={YOUR_API_TOKEN_KEY}

Query Parameter Notes
api_token Your API TOKEN KEY

Sample Request

GET /api/reports/10?api_token={YOUR_API_TOKEN_KEY}

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 423
Content-Type: application/json; charset=utf-8


{ "report": { "id": 10, "gender": "Female", "location": "Schaefermouth", "message": "Duchess, 'as pigs have to beat them off, and had just succeeded in getting its body tucked away, comfortably enough, under her arm, with its mouth and yawned once or twice, half hoping that they.", "created_at": "2017-08-16 07:44:01", "updated_at": "2017-08-16 07:44:01" } }

Updating report

PUT /api/reports/id?api_token={YOUR_API_TOKEN_KEY}

Field Required Notes
gender no Set of characters representing reporter gender
location no Set of characters representing reporter location
message no Set of characters representing reporter message

Sample Request


PUT /api/reports/10?api_token={YOUR_API_TOKEN_KEY}
Content-Type: application/json;


{ "gender":"Male", "location":"Temeke", "message":"Duka la dawa namba ab457c linauza dawa zilizoisha muda wa kutumika" }

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 180
Content-Type: application/json; charset=utf-8


{ "report": { "id": 10, "gender": "Male", "location": "Temeke", "message": "Duka la dawa namba ab457c linauza dawa zilizoisha muda wa kutumika", "created_at": "2017-08-16 07:44:01", "updated_at": "2017-08-16 12:55:22" } }

Creating a new report

POST /api/reports

Field Required Notes
gender yes Set of characters representing reporter gender
location yes Set of characters representing reporter location
message yes Set of characters representing reporter message

Sample Request


POST /api/v1/posts
Content-Type: application/json;


{ "gender":"Female", "location":"Kyela", "message":"Madawa yanauzwa bila vipimo kwenye duka namba 45sed23" }

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 656
Content-Type: application/json; charset=utf-8


{ "report": { "gender": "Female", "location": "Kyela", "message": "Madawa yanauzwa bila vipimo kwenye duka namba 45sed23", "updated_at": "2017-08-16 13:01:47", "created_at": "2017-08-16 13:01:47", "id": 11 } }

Removing report

DELETE /api/reports/id?api_token={YOUR_API_TOKEN_KEY}

Sample Request


DELETE /api/reports/11?api_token={YOUR_API_TOKEN_KEY}

It's response


Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 728
Content-Type: application/json; charset=utf-8


{ }