Download the PHP package honkio/honkio-php without Composer

On this page you can find all versions of the php package honkio/honkio-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package honkio-php

honkio/honkio-php

The official PHP SDK for HonkIO: Canadian SMS and email, with CASL built in. Data is stored in Canada (ca-central-1).

On Laravel? Use honkio/laravel for a mail transport and an SMS notification channel.

Install

Quickstart

Create a key in the dashboard under API Keys, Create key (https://honkio.ca/dashboard/keys); the full key is shown once, right after you create it. Start with a test key (mk_test_...): nothing is delivered or charged.

Send an SMS

new Honkio() with no argument reads HONKIO_API_KEY, and throws InvalidArgumentException if neither is set. Options: new Honkio($key, ['base_url' => ..., 'timeout' => 30, 'http_client' => $guzzle, 'max_retries' => 2, 'max_retry_delay' => 60]); see Retries.

Send an email

Email is transactional by default. Marketing email must set 'is_commercial' => true: it needs CASL consent on file for the recipient, goes to exactly one recipient, and carries an unsubscribe footer. Transactional email also reaches addresses that unsubscribed, so a promotion sent without the flag would get around the unsubscribe.

Errors

Every exception implements Honkio\Exception\HonkioException, so catch (HonkioException $e) catches them all.

Exception When
ApiException and its subclasses The API refused the request. $e->errorCode is the API's code (NO_CONSENT), $e->statusCode the HTTP status (also getCode()), $e->getMessage() its message, $e->details its details
ConnectionException No response arrived (DNS, refused connection, timeout). The send may or may not have happened
InvalidArgumentException A caller mistake caught before anything was sent: no API key, an empty or . or .. id, a consent call naming both or neither subject, a missing webhook secret
SignatureVerificationException A webhook could not be verified; see Webhooks

ApiException subclasses by status: BadRequestException (400), AuthenticationException (401), PaymentRequiredException (402), PermissionDeniedException (403), NotFoundException (404), ConflictException (409), UnprocessableEntityException (422), RateLimitException (429), UnavailableForLegalReasonsException (451), InternalServerException (5xx). A response whose body is not JSON (a proxy error page, say) has errorCode application_error.

details is the API's details when it sent one (validation paths, retry_after, missing template keys). Otherwise it holds whatever the API sent beside the error envelope: ['attempts_remaining' => 4] on VERIFICATION_INVALID_CODE.

The general codes and every SMS and email code are listed at https://honkio.ca/docs/errors.

Retries

The client sends a call again when the API refused it only because it should wait:

errorCode Retried
NUMBER_RATE_LIMITED (429) always: the sending number already has a minute of message parts waiting at the carrier (a local number sends 10 parts a minute)
CARRIER_THROTTLED (503) always: the carrier asked HonkIO to slow down and did not take the message; nothing was charged
CARRIER_UNAVAILABLE (503) always: the carrier could not be reached; nothing was sent or charged
RATE_LIMITED (429) on a GET or a send with an idempotency key. Elsewhere it can be the route's own limit, such as one verification start per recipient a minute, where a repeat would send again
ConnectionException on a GET or a send with an idempotency key: the request may have reached the API

Each retry waits as long as the API's Retry-After header (seconds, or an HTTP date to wait until) or details['retry_after_seconds'] says, or backs off exponentially with jitter when it says nothing. By default a call is retried at most 2 times, and a wait longer than 60 seconds is not waited out: the exception is thrown at once. When retrying does not help, the last exception is thrown, the same as without retries. The client waits with usleep(), so a retry blocks the PHP process for the wait.

Never retried: CARRIER_TIMEOUT (the message may have gone out: check its status with messages->get() before sending again), DAILY_LIMIT_REACHED, FANOUT_LIMIT_REACHED, RECIPIENT_RATE_LIMITED, SENDING_PAUSED, NUMBER_QUEUE_FULL, and every validation, consent or authentication error.

A local number sends 10 message parts a minute, so a burst bigger than that is spread out at that pace: each refusal says how long until there is room (about 6 seconds per part waiting). For a list, send to a contact group or pace your sends; for real volume, use a verified toll-free number. Do not spread one list across several numbers to go faster: carriers treat that as snowshoeing and it breaks the acceptable use policy.

Send limit and number queues

messages->send() returns the message with estimated_send_at: an ISO 8601 estimate of when the carrier should start sending it, from the parts already waiting on the sending number (null in test mode and on a retry that returned an earlier send). sendLimit->get() shows the rest before a burst: the daily cap and what is left of it, the per-recipient caps, probation, any pause, past volume requests, and number_queues, each number's carrier queue.

Idempotency

messages->send, emails->send and batch->send always send an Idempotency-Key header: the key you pass as their last argument, otherwise a generated UUID that stays the same on each retry of that call. The API answers a repeated key with the original result, so a retry can never send or charge twice.

The generated key covers only the client's own retries. If your code sends again after an exception (a queued job that runs again, say), pass your own key, derived from what is being sent (an order id), so the API recognises the repeat.

Request shapes

Parameters are arrays with the API's snake_case keys (scheduled_at, is_commercial, reply_to). A key you leave out is not sent; a key set to null is sent as JSON null, which clears a nullable field ($honkio->templates->update('welcome', ['html' => null])). In query parameters null means "not given" and is left out. A DateTimeInterface is converted to UTC and sent as ISO 8601 with a Z suffix (2026-10-14T16:30:00.000Z). The fields the API declares as plain dates (date_from and date_to on messages->list, last_transaction_date on consents->create) take a YYYY-MM-DD string; a DateTimeInterface passed there is sent as its UTC date.

An empty array for an object-typed field is sent as [], not {}; pass new \stdClass() for an empty object. The one exception is emails->send and batch->send, where an empty variables or headers map is always sent as {}. (On templates and emails->received->simulate the same keys are lists, and stay lists.)

Query lists repeat the key (['status' => ['a', 'b']] becomes status=a&status=b). Ids and other path values are separate string arguments: $honkio->webhooks->update($id, ['active' => false]). Deletes return null.

Resources

Property Methods
messages (SMS) send($params, $idempotencyKey) (the message plus estimated_send_at), get($id), list($query)
phoneNumbers areaCodes(), search($query) (area_codes may be a list), provision($params) (live keys; charges your balance), list(), get($id), release($id)
tollFreeVerifications options(), create($params), update($id, $params), submit($id), cancel($id), get($id), list($query)
businessVerification get() (null before a profile is saved), save($params), submit()
autoTopup get(): settings, saved card summary, pause state. Read-only
sendLimit get(): the daily cap and usage, per-recipient caps, probation, any pause, past volume requests, and number_queues; see Send limit and number queues
topupCapRequests create($params), list()
optInConfirmations send($params), list($query)
verify start($params), check($id, $params), get($id), list($query)
consents create($params), recordBatch($params), list($query), check($subject), revoke($subject)
consentBatches list($query), get($id)
webhooks create, list, get, update, remove, deliveries($id, $query), deadLetters($id, $query), replay($deadLetterId), discard($deadLetterId), reactivate($id), rotateSecret($id), verify($rawBody, $headers, $secret)
emails send($params, $idempotencyKey), get($id), list($query), update($id, $params), cancel($id)
emails->received list($query), address(), setAddressEnabled($enabled), get($id, $query), raw($id), attachment($id, $attachmentId) (both return the body as a string), simulate($params) (test keys only)
batch send($emails, $idempotencyKey): a list of up to 100 emails, or ['template' => ..., 'recipients' => [...]] for up to 500 recipients
domains create($params), get($id), list(), update($id, $params), verify($id), remove($id)
suppressions create(['email_address' => ...]), list($query), remove($emailAddress)
templates create, get($idOrAlias), list, update, publish, rollback($idOrAlias, ['version' => 2]), versions, remove

Honkio\Endpoints::ALL lists every route the SDK calls as [resource, method, HTTP method, path].

Consent

check and revoke take exactly one of phone_number or email_address; anything else throws InvalidArgumentException before a request is sent.

Receiving email

Webhooks

Check every delivery before you act on it. Pass the raw request body exactly as received, before any JSON parsing, and the headers.

The signature is HMAC-SHA256, keyed with the signing secret as UTF-8 (not hex-decoded), over "{X-HonkIO-Timestamp}.{raw body}". A timestamp more than 300 seconds from now is refused as a possible replay; pass a fourth argument to change that. Header names are matched case-insensitively and a value may be a string or a list of strings, so PSR-7 and Laravel header arrays work as they are. A missing secret throws InvalidArgumentException; anything about the headers, signature, timestamp or body throws SignatureVerificationException. Honkio\WebhookEvents::ALL lists every event a webhook can subscribe to. See https://honkio.ca/docs/webhooks/signing for the published test vector.

Development

Inside the HonkIO monorepo the tests read web/generated/openapi.json and fail when a route the SDK calls is missing from the API; in a standalone clone those tests skip.

Testing

The SDK classes are final, so they cannot be mocked. Build a Honkio with a Guzzle MockHandler instead and bind it where your code expects the client:

License

MIT


All versions of honkio-php with dependencies

PHP Build Version
Package Version
Requires php Version >=8.2
ext-json Version *
guzzlehttp/guzzle Version ^7.8
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package honkio/honkio-php contains the following files

Loading the files please wait ...