Resource Manager API
Overview
The Resource Manager API allows data providers the ability to upload multimedia files to the Clearinghouse and generate a public URL. These uploaded files are used with the RapidSOS Emergency Data APIs for data provisioning.
Data provisioning is a necessary step to ensure that media files are accessible via the RapidSOS CDN, which is already whitelisted through municipal firewalls, across the Clearinghouse coverage footprint.
After file upload, the generated URL should be used in any/all other Clearinghouse input APIs to reference the uploaded resource. The sample code shown in this document is a useful reference, but in general the flow is as follows:
- Get an authentication token
- Create an upload/download URL
- Upload the resource to the upload URL
- Use the download URL in subsequent data provisioning
Audience
This document is intended for developers that are familiar with RESTful APIs, authentication processes (tokens), and API integration. Knowledge of JSON and python programming language can be helpful when reviewing this material.
Authentication
The service is authenticated via short-lived OAuth 2.0 access tokens that are valid for 1 hour.
You must use both the “client credentials” and “password” grant types for obtaining an access token. These are described as follows:
- Client Credentials Grant Type: Used to authenticate your application’s access to the Multimedia Hosting API.
- Sandbox: https://api-sandbox.rapidsos.com/oauth/token
- Production: https://api.rapidsos.com/oauth/token
Headers
Name |
Type |
Value |
Content-Type |
string |
This will always be application/json |
POST Body
Name |
Type |
Value |
client_id |
string |
Your application credentials client ID |
client_secret |
string |
Your application credentials client secret |
grant_type |
string |
This should always be "client_credentials" |
Response
Name |
Type |
Value |
access_token |
string |
This is the Bearer token returned, to be used to make the POST request |
token_type |
string |
“Bearer” |
issued_at |
string |
Issued timestamp will always be the current time in ms |
expires_in |
string |
Expiration time, will always be 1hr in sec |
File Upload Endpoint
The main feature of this API is the ability to upload certain file types to RapidSOS managed cloud storage.
There are no restrictions on the file types or file sizes for this service - files will be opened by default in a new tab on a browser at PSAPs, so as general guidance it is recommended that file types be PDFs, standard media containers like MP3, MP4, AVI with codecs supported in browsers by default for playback, text files, images like PNGs or JPEGs, etc. It is also strongly recommended to keep file sizes below 10MB. Please plan to confirm with RapidSOS implementation support for any special use-cases.
The endpoint is:
- Sandbox: https://api-sandbox.rapidsos.com/v1/resources
- Production: https://api.rapidsos.com/v1/resources
This endpoint only accepts POST requests.
Formatting a Request
When formatting the POST request for the Multimedia Hosting API, you should have already received your bearer token to authenticate your request.
Headers
Name |
Type |
Value |
Content-Type |
string |
This will always be application/json |
Authorization |
string |
This will be “Bearer XXXXXXXX” including your auth bearer token as the X’s. |
POST Body
Name |
Type |
Value |
file_name |
string |
Filename to upload (spaces must be excluded) |
mime_type |
string |
File type to upload, must be one of the supported values. Must be in all lowercase. ‘mime_type’’ accepts a limited number of MIME file types. ● The currently supported MIME file types are: ○ application/pdf ○ application/msword ○ application/rtf ○ video/* ○ audio/* ○ image/* ○ text/markdown ○ text/rtf ○ text/plain ○ application/octet-stream Where * denotes a wildcard. |
expire |
integer |
File expiration (in seconds) - when the file can be deleted. Optional (default 600 seconds). This field is ignored if mode is set to persistent. The field should be omitted when using persistent_reference. |
mode |
string |
Either “temporary_url” or “persistent_reference” |
● These values must be in JSON format when included in the body of the POST request.
● When using “persistent_reference”, the expected uri output will contain “ref://” rather than “https://”
Response
Name |
Type |
|
uri |
string |
URL for downloading this file |
signed_request
|
object |
The signature for the upload.
The signature includes two fields: ● url : the URL to upload the file to ● fields : additional fields that the upload requires |
The uri is a temporary URL generated by AWS for the purpose of accessing/downloading the uploaded file. This URL should be passed through to our Emergency Data API so it can be leveraged by RapidSOS Portal and any Partner integrations.
Potential Response Codes
Code |
Description |
200 |
Success |
400 |
Request is malformed |
401 |
Client is unauthorized |
429 |
The client has made too many requests to this endpoint |
Resolving ref://
When using the “Persistent_reference” mode the URI returned must be resolved to an https:// URL. The reason for this is to support the download of uploaded media via RapidSOS support APIs.
Endpoint: /v1/resources/{}/resolve
To receive a “resolved” ref:// just replace {} with the reference URI, something like:
/v1/resources/{ref://xxxx-xxxxx-xxxxx-xxxx}/resolve
This will output if successful:
https://api-sandbox.rapidsos.com/v1/resources/XXXX
Headers
Name |
Type |
Value |
Content-Type |
string |
This will always be application/json |
Authorization |
string |
This will be “Bearer XXXXXXXX” including your auth bearer token as the X’s. |
Potential Response Codes
Code |
Description |
200 |
|
400 |
Request is malformed |
401 |
Client is unauthorized |
429 |
The client has made too many requests to this endpoint |
Sample Code
NOTE: this example requires the requests python library (https://requests.kennethreitz.org/en/master/)
import json
import random
import sys
import string
import requests
# API_HOST: target hostname (without https:// prefix or path..)
API_HOST = "api-sandbox.rapidsos.com"
# CREDENTIALS
OAUTH_CLIENT_ID = "XXXXXXXXXXXXXXXXXX"
OAUTH_CLIENT_SECRET = "XXXXXXXXXXXXXXXX"
def main():
# Step 1: Authentication
# Authenticate with your RapidSOS client_ID and client_secret
access_token = authenticate()
# =======================================================
# First upload the file and get a url
# =======================================================
# Step 2: Request upload
# Request an upload link to upload for the media file
data = request_upload(access_token)
# Step 3: Upload
# Upload the media file to the requested url
# Includes required logic to resolve a file URL ONLY when mode = persistent_reference in Step 2
data_url = upload(data, access_token)
# =======================================================
def authenticate():
OAUTH_URL = "https://api-sandbox.rapidsos.com/oauth/token"
print("Step 1: Authentication\n", f"POST {OAUTH_URL}...", sep="")
payload = {
"client_id": OAUTH_CLIENT_ID,
"client_secret": OAUTH_CLIENT_SECRET,
"grant_type": "client_credentials"
}
response = requests.post(OAUTH_URL, data=payload)
if response.status_code != 200:
print(f"Authentication Request failed: status code={response.status_code}")
print(response.text)
sys.exit(1)
data = response.json()
access_token = data['access_token']
print('\tAuthentication Successful\n')
return access_token
def request_upload(access_token):
url = "https://api-sandbox.rapidsos.com/v1/resources"
print("Step 2: Request Upload\n", f"POST {url}...", sep="")
file_name = "test.jpg"
mime_type = "image/jpg"
expire = 120
mode = "temporary_url"
payload = {
"file_name": f"{file_name}",
"mime_type": f"{mime_type}",
"expire": f'{expire}',
"mode": f'{mode}'}
headers = {
'Content-Type': "application/json",
'Authorization': f"Bearer {access_token}"
}
response = requests.post(url, json=payload, headers=headers)
if response.status_code != 200:
print(f"Request failed: status code={response.status_code}")
print(response.text)
sys.exit(1)
data = response.json()
print("\tUpload Parameters:", payload)
print(f"\tData URL: {data['uri']}\n")
return data
def upload(data, access_token):
upload_url = data["signed_request"]["url"]
data_url = data["uri"]
print("Step 3: Upload File\n", f"POST {upload_url}...", sep="")
fields = data["signed_request"]["fields"]
files = {"file": open('test.jpg', 'rb')}
headers = {
'Content-Type': "application/json",
'Authorization': f"Bearer {access_token}"
}
response = requests.post(url=upload_url, data=fields, files=files)
if response.status_code not in (204, 200):
print(f"Request failed: status code={response.status_code}")
print(response.text)
sys.exit(1)
if data_url[:6] == 'ref://':
url = "https://{}/v1/resources/{}/resolve".format(API_HOST, data['uri'][6:])
print(url)
print("Step3: GET {}...".format(url))
response = requests.get(url=url, headers=headers)
else:
print('Resolve reference failed: Invalid scheme you passed am already resolved URL')
print(data_url)
print('\tUpload Successful\n')
sys.exit(1)
if response.status_code != 200:
print("Request failed: status code={}".format(response.status_code))
print(response.text)
sys.exit(1)
data = response.json()
print(data)
print('\tUpload Successful\n')
return data_url
# Launch main function
main()