ReportingCloud

Authentication

Topic

The Authorization header of a request tells the ReportingCloud Web API which account the request acts for. It holds either an API key or the user name and password of the account. There is no token to request first and no session to open: the header travels with each call, whether curl, an SDK or your own HTTP client sends it. Read on for the two header formats, how each SDK builds them and what the service answers when the credentials are missing or wrong.

How Authentication Works

The Web API accepts two kinds of credentials, and each request carries exactly one of them:

MethodHeaderBuilt from
API keyAuthorization: ReportingCloud-APIKey <key>An API key of your account, unchanged
BasicAuthorization: Basic <credentials>The user name, which is the email address of the account, and the password, joined by a colon and Base64-encoded

Text Control recommends API keys over Basic authentication; API Keys gives the reasons and shows how to create and delete keys. A key opens your account, its data and its templates to whoever holds it, and every document they create counts against your quota, so treat it like a password and keep it out of source code and repositories.

All endpoints are below https://api.reporting.cloud/v1/, and the Web API answers on HTTPS only, so the credentials are always sent encrypted. A request to http://api.reporting.cloud gets no answer.

Authenticate With an API Key

Keep the key in an environment variable and send it in the header. The following request asks for the number of templates in your template storage, which counts against none of the quotas:

export REPORTINGCLOUD_API_KEY="<API key>"

curl "https://api.reporting.cloud/v1/templates/count" \
  -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY"

The response body is the number, for example 3. What the request shows:

  • The header value is the word ReportingCloud-APIKey, a space and the key. The word and the key are matched regardless of case, so reportingcloud-apikey works as well.
  • The same header works for every endpoint, with GET, POST, PUT and DELETE requests alike.
  • Endpoints that take a JSON body also need -H "Content-Type: application/json", as the samples on the following pages show.

Authenticate With User Name and Password

Basic authentication sends the credentials of the account itself. curl builds the header from --user:

curl "https://api.reporting.cloud/v1/templates/count" \
  --user "<email address>:<password>"

Another HTTP client needs the header written out:

  1. Join the user name and the password with a colon, for example user@example.com:password.

  2. Encode the string as Base64 on one line, without line breaks. In a shell, printf '%s' 'user@example.com:password' | base64 -w 0 does it.

  3. Put the word Basic and a space in front of the result:

    Authorization: Basic dXNlckBleGFtcGxlLmNvbTpwYXNzd29yZA==
    

The word Basic and the user name are matched regardless of case.

Basic authentication sends your password with every request, and code that uses it stops working when the password changes. Use an API key wherever your client supports one.

Authenticate With the SDKs

Each SDK takes the credentials once, when you create its ReportingCloud object, and adds the header to every request it sends:

SDKWith an API keyWith user name and password
.NET, package TXTextControl.ReportingCloudnew ReportingCloud(apiKey)new ReportingCloud(username, password)
PHP, package textcontrol/textcontrol-reportingcloudnew ReportingCloud(['api_key' => $apiKey])The options 'username' and 'password', marked as deprecated
JavaNot supportednew ReportingCloud(username, password)
RubyNot supportedReportingCloud.new(username, password)

The Java and Ruby SDKs always send a Basic header. Their API key methods, such as createAPIKey and create_api_key, manage the keys of the account but don't use them. SDKs compares the four.

The following .NET console application authenticates with an API key and prints the number of templates in the storage:

using TXTextControl.ReportingCloud;

// Read the API key from an environment variable instead of the source code
string apiKey = Environment.GetEnvironmentVariable("REPORTINGCLOUD_API_KEY")
    ?? throw new InvalidOperationException("Set REPORTINGCLOUD_API_KEY first.");

// Every request of this instance sends "Authorization: ReportingCloud-APIKey <key>"
ReportingCloud rc = new ReportingCloud(apiKey);

int count = rc.GetTemplateCount();
Console.WriteLine($"Templates in the storage: {count}");

The code works as follows:

  • The ReportingCloud constructor with one string takes an API key. Further constructors take the base URL of the Web API as a Uri as their last argument, ReportingCloud(apiKey, webApiBaseUrl) and ReportingCloud(username, password, webApiBaseUrl); without it, the SDK uses https://api.reporting.cloud.
  • When an API key is set, the SDK sends it. Otherwise, it builds a Basic header from the Username and Password properties.
  • GetTemplateCount sends GET /v1/templates/count and returns the number.

Install the package with dotnet add package TXTextControl.ReportingCloud, as Installing an SDK shows.

In PHP, the key goes into the 'api_key' option of the constructor, new ReportingCloud(['api_key' => (string) getenv('REPORTINGCLOUD_API_KEY')]), or into setApiKey() of an existing object before its first request: the SDK builds the header once, for the first request, and ignores a key set later. Without an API key and without a user name and password, the PHP SDK sends nothing: its first request throws an InvalidArgumentException with the message "Either the API key, or username and password must be set for authorization".

Call the Web API From a Browser

The Web API allows cross-origin requests from any origin: it answers with Access-Control-Allow-Origin: * and accepts the Authorization and Content-Type headers in them. A script in a web page could therefore call it, but the key or password it sends would be visible to every visitor of the page. Send the requests from your server and pass only the results to the browser, as Data Security and Privacy explains.

When Authentication Fails

What a client sees depends on what is wrong:

  • Credentials that aren't authorized. An unknown or deleted API key, or a wrong user name or password, gets 403 Forbidden with the plain-text body Invalid username/password combination or invalid APIKey. The endpoints with a quota answer 403 as well when the quota is exceeded.

  • No valid Authorization header. A request without credentials, with an empty Authorization header or with one that is not the authorization method, a space and the credentials, such as ReportingCloud-APIKey: followed by the key, gets 500 Internal Server Error instead, with this body:

    {"Message":"An error has occurred."}
    
  • In the SDKs. The .NET SDK throws an ArgumentException whose message is the response body. The PHP SDK throws a TextControl\ReportingCloud\Exception\RuntimeException whose code is the HTTP status.

Troubleshooting: Authentication lists the causes and their fixes, and Errors and Status Codes explains every answer of the Web API.

Next Steps