NAV Navbar
ruby javascript

Introduction

Thanks for your interest in the Gig Wage API. We look forward to seeing what you build!

In order to get an API key for your integration, please complete the .

Requests and responses

Payloads for POST, PUT and PATCH requests are expected to be JSON. Responses are JSON.

The base URL for the API depends on the environment:

Sandbox Onboarding

Once you've been granted API access you'll need to onboard your business in the sandbox with valid test values. Some form fields accept arbitrary values, but the following fields need values that follow their sandbox rules, for successful integrations with our sandbox partners:

Screen Field Rule
Onboarding First Name Must be 2 or more alpha characters
Onboarding Last Name Must be 2 or more alpha characters
Onboarding Date of Birth Must put you at 18 years of age or older
Onboarding Phone Number Must have the form of a valid phone number (easiest solution is to use your real one)
Onboarding Social Security Number Must be 9 digits, the last 4 of which are 2222
Onboarding Business Name Must be 2 or more alpha characters
Onboarding EIN Must be 9 digits, the last 4 of which are 2222
Onboarding Address
1 Market Street
San Francisco, CA
94105
Bank Account Authorization Username Use user_good
Bank Account Authorization Password Use pass_good

Authentication

Authenticating against the API requires 3 request headers:

API key

The X-Gw-Api-Key request header contains the "key" portion of the API key pair issued to your business.

request.headers['X-Gw-Api-Key'] = api_key

Timestamp

The X-Gw-Timestamp request header contains the UNIX epoch (UTC) in milliseconds. Some implementations of strftime provide this as %Q. In Ruby for example:

timestamp = DateTime.now.strftime('%Q')
request.headers['X-Gw-Timestamp'] = timestamp

If this is unavailable in your language or framework, multiplying the epoch by 1000 will be adequate.

Signature

The X-Gw-Signature request header contains a SHA256 HMAC signature of the X-Gw-Timestamp header, using your secret key, in hex format.

timestamp = DateTime.now.strftime('%Q')
signature = OpenSSL::HMAC.hexdigest("SHA256", my_secret_key, timestamp)
var CryptoJS  = require("crypto-js");
var timestamp = (new Date).getTime().toString();
var bytes     = CryptoJS.HmacSHA256(timestamp, my_secret_key);
var signature = bytes.toString(CryptoJS.enc.Hex);

Using CryptoJS

Authentication Summary

Every authenticated request, then, will contain all 3 of these headers:

request.headers['X-Gw-Api-Key']   = api_key
request.headers['X-Gw-Timestamp'] = timestamp
request.headers['X-Gw-Signature'] = signature

The API will respond with an authentication error if: * The API key is missing, invalid, revoked, or not associated with the secret key used to generate the signature * The timestamp header is missing, invalid, or not within 60 seconds of the server's clock * The signature header is anything but the correct signature for the supplied timestamp using the secret key associated with the provided API key

Endpoints

Payments

GET /api/v1/payments/{id}

Returns the details for a single payment, including an array of line item details and the id of the contractor associated with the payment.

client.get("/api/v1/payments/1234")

Example JSON response

{
  payment: {
    id: 1234,
    amount: "12.34",
    line_items: [
      {
        id: 2345,
        amount: "12.34",
        reason: "11/5 payroll",
        reimbursement: false,
        job_id: null,
        external_id: null
      }
    ],
    external_id: null,
    contractor_id: 1004,
    created_at: "2019-05-02T00:18:07.802Z",
    status: "completed"
  }
}

GET /api/v1/payments

Returns a list of payments, sorted newest-first

Parameters

All parameters are optional and should be passed as a query string on the URL:

Parameter Description
size The number of records to return. Default is 200, max is 200.
page For paginated results, the page number to return. For example, ?size=100&page=2 will return payments 101-200.
client.get("/api/v1/payments?size=1&page=1")

Example JSON response

payments: [
  {
    id: 1234,
    amount: "123.0",
    line_items: [
     {id: 2345, amount: "123.0", reason: "11/5 payroll", reimbursement:false, job_id: null, external_id: null}
    ],
    external_id: null,
    contractor_id: 1004,
    created_at: "2019-05-02T00:18:07.802Z",
    status: "completed"
  }
]

POST /api/v1/payments

Creates a new payment to a contractor

Parameters

Parameter Description
nonce A unique value for idempotency to help prevent accidental duplicate payments (string, required)
payment The root of the payload (required)
contractor_id The id of the contractor to be paid (integer, required)
line_items An array of line items (array, required)
amount The amount of the line item in dollars (decimal, required)
reason The reason for this line item (string, optional)
reimbursement Whether this line item is a reimbursement (boolean, optional)
external_id Your identifier for this payment (string, optional)
interchange Whether to send payment to a contractor's debit card if possible (boolean, optional)
client.post("/api/v1/payments", {
  payment: {
    nonce: 'abc123',
    contractor_id: 1004,
    line_items: [
      {
        amount: 123.0,
        reason: "11/5 payroll",
        reimbursement: false
      }
    ],
    interchange: nil
  }
})

Example JSON response

payments: [
  {
    id: 1234,
    amount: "123.0",
    line_items: [
     {id: 2345, amount: "123.0", reason: "11/5 payroll", reimbursement: false, job_id: null, external_id: null}
    ],
    external_id: null,
    contractor_id: 1004,
    created_at: "2019-05-02T00:18:07.802Z",
    status: "completed"
  }
]

Details on the nonce parameter: The value will be cached by the API for 24 hours. During this window it must be unique. Once a value has been used, any subsequent requests to this endpoint using the same value for the nonce will fail. This is by design, in order to prevent the accidental creation of duplicate payments.

Details on the interchange parameter: If true, and the payment satisfies requirements for instant payout via debit card, other logic is overridden and the payment will be sent to the contractor's debit card. If false, and the contractor has another payment method available, the payment will not be sent to the contractor's debit card even if the payment meets requirements. If nil/null or omitted, payment will be routed according to default logic.

Contractors

GET /api/v1/contractors/{id}

Returns the details for a given contractor

Parameters

Parameter Description
id Replace {id} in the URL with the id of the contractor
client.get("/api/v1/contractors/1004")

Example JSON response

{
  contractor: {
    id: 1004,
    email: "karen@example.com",
    first_name: "Karen",
    last_name: "Example",
    created_at: "2019-05-03T22:18:16.965Z",
    invited_at: "2019-05-03T22:18:16.965Z"
  }
}

GET /api/v1/contractors

Parameters

All parameters are optional and should be passed as a query string on the URL:

Parameter Description
size The number of records to return. Default is 200, max is 200.
page For paginated results, the page number to return. For example, ?size=100&page=2 will return contractors 101-200.
client.get("/api/v1/contractors?size=1&page=1")

Example JSON response

{
  contractors: [
    {
      id: 1004,
      email: "karen@example.com",
      first_name: "Karen",
      last_name: "Example",
      created_at: "2019-05-03T22:18:16.965Z",
      invited_at: "2019-05-03T22:18:16.965Z"
    }
  ]
}

POST /api/v1/contractors

Creates a new contractor.

Parameters

Parameter Description
contractor The root of the payload (required)
first_name The contractor's first name (string, required)
last_name The contractor's last name (string, required)
email The contractor's last name (string, required)
client.post("/api/v1/contractors", {
  contractor: {
    first_name: 'Karen',
    last_name: 'Example',
    email: 'karen@example.com'
  }
})

Example JSON response

{
  contractors: [
    {
      id: 1004,
      email: "karen@example.com",
      first_name: "Karen",
      last_name: "Example",
      created_at: "2019-05-03T22:18:16.965Z",
      invited_at: "2019-05-03T22:18:16.965Z"
    }
  ]
}

PATCH /api/v1/contractors/{id}

Updates an existing contractor. If the contractor has already registered, changes to the email address will not affect email delivery: emails will be delivered to the address managed by the contractor. Any supported attributes not supplied in the request will not be changed.

Parameters

Parameter Description
contractor The root of the payload (required)
first_name The contractor's first name (string, optional)
last_name The contractor's last name (string, optional)
email The contractor's last name (string, optional)
client.patch("/api/v1/contractors", {
  contractor: {
    email: 'karene2@example.com'
  }
})

Example JSON response

{
  contractor: {
    id: 1004,
    email: "karen@example.com",
    first_name: "Karen",
    last_name: "Example",
    created_at: "2019-05-03T22:18:16.965Z",
    invited_at: "2019-05-03T22:18:16.965Z"
  }
}

POST /api/v1/contractors/{id}/invite

Delivers a secure onboarding email invitation to an existing contractor who has never been paid. If the contractor has an outstanding unaccepted invitation, the old invitation will be invalidated.

Parameters

No parameters are required or accepted

client.post("/api/v1/contractors/1004/invite")

Example JSON response

{
  contractor: {
    id: 1004,
    email: "karen@example.com",
    first_name: "Karen",
    last_name: "Example",
    created_at: "2019-05-03T22:18:16.965Z",
    invited_at: "2019-05-03T22:18:16.965Z"
  }
}

Errors

The Gig Wage API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- Not for you bruh.
404 Not Found -- The resource you could not be found.
429 Too Many Requests -- Slow ya roll!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.