(Click here to visit App-Ray homepage: app-ray.co)


Standard API endpoint:
   
{your_instance}/api/v1/

App-Ray uses Bearer authorization tokens for authenticated sessions.

Every public API request (except the authentication-related ones) requires
Bearer authorization token to be set in the HTTP request header.
See example below.

The API details are available in YAML format - click here to download .yaml file.

Another example:

If your App-Ray instance is located at:
https://appscan.yourcompany.com/

    Your API endpoint would be:
https://appscan.yourcompany.com/api/v1/
Example:

If your domain is
https://demo.app-ray.co/

    Your API endpoint will be:
https://demo.app-ray.co/api/v1/




POST
Do user authentication

/authentication


Parameters:
username
Name:
username
Type:
string
In:
formData
Required:
true

password
Name:
password
Type:
string
Format:
password
In:
formData
Required:
true

grant_type
Name:
grant_type
Type:
string
In:
formData
Required:
true
Default:
password


Responses:
200         Authentication successful
401         Authentication failed
Examples:
POST /api/v1/authentication

formData:
  username=username@email.org
  password=my_secret_password_123
  grant_type=password

returns 200:OK
{
    "access_token": "abcdef123456",
    "expires_in": 86400,
    "last_login_ip": "86.87.88.89",
    "last_login_successful": true,
    "last_login_time": 1515636522,
    "token_type": "Bearer"
}

Note: the access token should be used for identification in all further requests. The following HTTP request header should be set:
Authorization: Bearer abcdef123456
(where the token value is received after successful login via /authentication endpoint, as described above.)


GET
Retrieve scanning jobs

/jobs


Parameters:
status
Name:
status
In:
query
Description:
Filter jobs by status (pending is queued & processing, done is finished & failed)
Type:
string
Enum:
[queued,processing,finished,failed,pending,done,all]
Default:
pending

submitter
Name:
submitter
In:
query
Description:
Filter by submitter
Type:
string

package
Name:
package
In:
query
Description:
Filter by package name (partial and case insensitive)
Type:
string

label
Name:
label
In:
query
Description:
Filter by label (partial and case insensitive)
Type:
string

app_hash
Name:
app_hash
In:
query
Description:
Filter by the app_hash (partial and case insensitive)
Type:
string

threat_ids
Name:
threat_ids
In:
query
Description:
Filter by any threat ID
Type:
string

_sort
Name:
_sort
In:
query
Description:
Sort results by the specified field using native sorting (can be combined with other filters)
Type:
string
Enum:
[risk_score,timestamp_scan_finish]

_limit
Name:
_limit
In:
query
Description:
Limit number of returned jobs
Type:
integer


Responses:
200         List of jobs
Examples:
GET /api/v1/jobs

returns 200: OK
[
  {
    "uuid": "32523252c923-4772-4417-a7cb",
    "package": "com.appray.test.app",
    "label": "Test App",
    "version": "1.0.1",
    "app_hash": "8e3aa19fdc42e87659746f6dc",
    "timestamp_upload": 1473265825,
    "timestamp_scan_start": 1473266000,
    "timestamp_scan_finish": 1473267000,
    "status": "finished",
    "submitter": "user@example.com",
    "notification_group": "5a7c2a8f-8625-40e7-9b77",
    "progress_total": 20,
    "progress_finished": 20,
    "risk_score": 80,
    "risk_grade": "F",
    "threat_counts": {
      "total": 10,
      "high": 5,
      "medium": 3,
      "low": 2
    }
  }
]


GET /api/v1/jobs?status=pending&_sort=risk_score

returns: 200
[]





POST
Submit application for scanning

/jobs


Parameters:
file
Name:
file
In:
formData
Description:
application binary
Type:
file
Required:
true

notification_group
Name:
notification_group
In:
formData
Description:
ID of the notification group to be notified on scan execution
Type:
string
Format:
uuid


Responses:
202         Submitted application is queued for scanning
409         Application can not be queued for scanning (limit, license, notification group missing)
413         Submitted binary is too big
415         Submitted binary is not a supported application type
default         Temporary processing error
Examples:
POST /api/v1/jobs

formData:
  file=testapp.apk
  config={"dynamic_scan_mode":"interactive"}

returns 202: Accepted
"1118eb90-f65f-11e7-9f9d-0242cc110008"
(which is the UUID of the recently created analysis session)


returns 415: Unsupported Media Type
{
    "detail": "The provided file is not a valid file.",
    "status": 415,
    "title": "No valid application found",
    "type": "about:blank"
}





POST
Submit application URL to retrieve for scanning

/job_url


Parameters:
url
Name:
url
In:
formData
Description:
URL of the app
Type:
string
Required:
true

notification_group
Name:
notification_group
In:
formData
Description:
ID of the notification group to be notified on scan execution
Type:
string
Format:
uuid


Responses:
202         Submitted application is queued for scanning
400         Invalid URL submitted, application is not available at the given URL
401         Application is not available at the given URL (Access Denied)
404         Application is not available at the given URL (File Not Nound)
408         The given URL is not responding
409         Application can not be queued for scanning (limit, license, notification group missing)
413         Submitted binary is too big
415         No valid application file found at the specified location
default         Temporary processing error
Examples:
POST /api/v1/job_url

formData:
  url=http://app-ray.co/testapp.apk
  config={"dynamic_scan_mode":"interactive"}

returns 202: Accepted
"1118eb90-f65f-11e7-9f9d-0242cc110008"
(which is the UUID of the recently created analysis session)


returns 415: Unsupported Media Type
{
    "detail": "The provided file is not a valid file.",
    "status": 415,
    "title": "No valid application found",
    "type": "about:blank"
}





GET
Retrieve job summary

/jobs/{job_id}


Parameters:
job_id
Name:
job_id
In:
path
Description:
the ID of job
Type:
string
Required:
true


Responses:
200         Job summary
404         The given job ID does not exist
Examples:
GET /jobs/1118eb90-f65f-11e7-9f9d-0242cc110008

returns 200: Job summary
{
  "uuid": "3252c923-4772-4417-a7cb",
  "package": "com.appray.test.app",
  "label": "Test App",
  "version": "1.0.1",
  "app_hash": "8e3aa19fdc42e87659746f6",
  "timestamp_upload": 1473265825,
  "timestamp_scan_start": 1473266000,
  "timestamp_scan_finish": 1473267000,
  "status": "finished",
  "submitter": "user@example.com",
  "notification_group": "5a7c2a8f-8625-40e7-9b77",
  "progress_total": 20,
  "progress_finished": 20,
  "risk_score": 80,
  "risk_grade": "F",
  "threat_counts": {
    "total": 10,
    "high": 5,
    "medium": 3,
    "low": 2
  },
  "scan_duration": 35000,
  "scan_errors": {
    "detector.a.b": "Something reallly bad has happened"
  },
  "threat_summaries": [
    {
      "id": "DEBUGGABLE",
      "explanation": "Details to include here",
      "description": "App is debuggable"
    }
  ]
}




DELETE
Delete job

/jobs/{job_id}


Parameters:
job_id
Name:
job_id
In:
path
Description:
the ID of job
Type:
string
Required:
true


Responses:
200         Job
404         The given job ID does not exist
Examples:
DELETE /jobs/1118eb90-f65f-11e7-9f9d-0242cc110008

returns 200
OK




GET
Retrieve the application icon

/jobs/{job_id}/icon.png


Parameters:

Responses:
200         Scanned application icon
404         Application icon for the given job ID does not exist


GET
Retrieve the application detector details

/jobs/{job_id}/details


Parameters:
path
Name:
path
In:
query
Description:
jsonpointer path to retrieve (rfc6901)
Type:
string


Responses:
200         Scanned application detector details
404         The given job ID does not exist
Examples:
GET /api/v1/jobs/30e789e4-
0cdc-11e7-8789/details?path=/de.fhg.aisec.appray.detectors...

returns 200: Scanned application detector details
[
  {
    "cause": "SQLiteDatabase.rawQuery() called with
modifiable query string",
    "origin": "Lcom/umeng/common/net/c;->a(I)V"
  },
  {
    "cause": "SQLiteDatabase.rawQuery() called with
modifiable query string",
    "origin": "Lcom/umeng/common/net/c;->a(I)V"
  },
  {
    "cause": "SQLiteDatabase.rawQuery() called with
modifiable query string",
    "origin": "Lcom/umeng/common/net/c;->a(I)V"
  }
]




GET
Retrieve the application result files zipped

/jobs/{job_id}/result.zip


Parameters:
Array ( [200] => Array ( [description] => Scanned application detector result zip ) [404] => Array ( [description] => The given job ID does not exist ) )

Responses:
200         Scanned application detector result zip
404         The given job ID does not exist


GET
Retrieve the application result report as pdf

/jobs/{job_id}/report.pdf


Parameters:
Array ( [200] => Array ( [description] => Report PDF ) [404] => Array ( [description] => The given job ID does not exist ) )

Responses:
200         Report PDF
404         The given job ID does not exist


GET
Retrieve part of the application source code

/jobs/{job_id}/source


Parameters:
path
Name:
path
In:
query
Description:
path to the requested class\/method
Type:
string
Required:
true


Responses:
200         Matching source blocks in utf8 encoded plain text
404         The given job ID or source path does not exist


GET
Search contained strings

/jobs/{job_id}/strings


Parameters:
string
Name:
string
In:
query
Description:
string using globbing to search for
Type:
string
Required:
true


Responses:
200         String occurences
404         The given job ID does not exist


GET
Retrieve the virus scan results for the given job

/jobs/{job_id}/virus-results


Parameters:

Responses:
200         Virus scan results
404         The given job ID does not exist


GET
Retrieve information on the organization

/organization


Parameters:

Responses:
200         Information on the user's organization


GET
Retrieve statistics on the operation

/organization/statistics


Parameters:

Responses:
200         Statistics


GET
Retrieve the configuration of the organization

/organization/configuration


Parameters:

Responses:
200         the configuration object


POST
Save organization configuration

/organization/configuration


Parameters:
body
Name:
body
In:
body
Required:
true
Schema:
{type:object,description:the configuration object}


Responses:
200         Configuration saved successfully
400         Error updating credentials


GET
Retrieve information on the user

/user


Parameters:

Responses:
200         User summary


POST
Change user credentials

/user/credential


Parameters:
body
Name:
body
In:
body
Required:
true
Schema:
{type:object,description:Password update,properties:{old_password:{type:string,format:password,description:Current password of the user},new_password:{type:string,format:password,description:New password of the user}},required:[old_password,new_password]}


Responses:
200         Credentials updated successfully
400         Error updating credentials


POST
Request a one-time login when credentials lost

/lost-credential


Parameters:
body
Name:
body
In:
body
Required:
true
Schema:
{type:string,format:email,description:Email of the user with the lost credentials}


Responses:
200         One-time login sent


POST
Send support question

/support


Parameters:
body
Name:
body
In:
body
Required:
true
Schema:
{type:object,description:Support question}


Responses:
200         Authentication successful