API Calls
url
urls
file
file_part_initialize
file_part_upload
file_part_finalize
change_shorturl
set_enabled
set_tag
set_expiration_count
delete
get_entry
get_entries
get_protected_file_info
get_signature
temporary_account
signup
login
logout
change_password
check_credentials
forgot_password
reset_password
verify_email
get_account_info
multi

url

POST /v2/url

Shortens a given url. If 'host' is not given, the default is 'ww7.io' which produces https://ww7.io/123456. If 'code' is provided (it is the '123456' part of the shortened url) and it belongs to the user, this call functions as 'replace' and replaces the old entry for the given code.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


url     str - required

The full URL to be shortened. Example: 'https://www.example.com/a_very_lonh_url.html'


expiration_utime     int64 - optional (default: 576460752303423487)

Expiration time given in unix-time in microseconds. Default is 0x7ffffffffffffff.


tag     int64 - optional (default: 0)

Each bit defines a logical tag. This tag can be used as filter for get_entries.


expiration_count     int - optional (default: 0)

Short URL expires after this many number of clicks. Setting 0 disables the click-count-expiration.


host     str - optional (default: ww7.io)

Requested base host of shortened url. The available hosts are: ww7.io


code     str - optional

Provided to replace an existing shortened url or to use it if it does not belong to another used. Must be [6,16] in length, and contains only 26 letters in small and caps, and numbers.


shorturl     str - optional

Shortened url to be used. Ex: https://ww7.io/sD4fSa. If this parameter is provided, host and code parameters will be ignored.


qr     dict - optional

If provided, entry output returns 'qrcode' containing an image of the QR code of shortened link. The dictionary can have the following keys describing the format:

        format : Can be 'svg' or 'png'. Default: 'svg'
        border : Border around the QR code in background color. Default: 3
        fg : Foreground color. Default: '#000000' (black)
        bg : Background color. Default: '#ffffff' (white)
        level : Error correction level of QR code. Default: 'M'

Some or all key values can be omitted. Defaults will be used for the omitted values. (query['qr'] = {} yields an image completely formatted by the defaults.) Colors must be in #rrggbb or #rrggbbaa format. If aa (alpha) channel is given, transparency can be defined. 'level' can be L, M, Q, H representing the low, medium, quartile, high. Percentage of data that can be restored for each level is 7%, 15%, 25%, and 30% respectively.




OUTPUT ITEMS

entry     dictionary - always exists

Entry for the shortened URL pointing the original URL for redirection. Dictionary items are listed at get_entry





urls

POST /v2/urls

Functions like url, but shortens a list of URLS. The maximum number of URLS is 1000.

Weight: 1000 per call + 100 per url


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


urls     list - required

List of URLS to be shortened. Example: ['https://www.example.com/','https://www.mit.edu/']


expiration_utime     int64 - optional (default: 576460752303423487)

Expiration time given in unix-time in microseconds. Default is 0x7ffffffffffffff.


tag     int64 - optional (default: 0)

Each bit defines a logical tag. This tag can be used as filter for get_entries.


expiration_count     int - optional (default: 0)

Short URL expires after this many number of clicks. Setting 0 disables the click-count-expiration.


host     str - optional (default: ww7.io)

Requested base host of shortened url. The available hosts are: ww7.io


qr     dict - optional

If provided, entry output returns 'qrcode' containing an image of the QR code of shortened link. The dictionary can have the following keys describing the format:

        format : Can be 'svg' or 'png'. Default: 'svg'
        border : Border around the QR code in background color. Default: 3
        fg : Foreground color. Default: '#000000' (black)
        bg : Background color. Default: '#ffffff' (white)
        level : Error correction level of QR code. Default: 'M'

Some or all key values can be omitted. Defaults will be used for the omitted values. (query['qr'] = {} yields an image completely formatted by the defaults.) Colors must be in #rrggbb or #rrggbbaa format. If aa (alpha) channel is given, transparency can be defined. 'level' can be L, M, Q, H representing the low, medium, quartile, high. Percentage of data that can be restored for each level is 7%, 15%, 25%, and 30% respectively.




OUTPUT ITEMS

entries     list - always exists

List of entries for the shortened URLS pointing the original URLS for redirection. Dictionary items in each element are listed at get_entry





file

multi-form POST /v2/file

Sends a file for sharing. A shortened link is created to access the file. The file can be encrypted with a requeted method (AES-256 is available for know). Encryption/decryption happens on the client side, in browser or client application. The server will have no knowledge of the password encrypting the file.

'query' and 'files' parts must exists in the multi-form post. 'query' contains the input parameters.

Weight: 1000 per call + 100 per MB of data


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


filename     str - required

Name of the file.


filesize     int64 - required

Size of the file in bytes.


filetype     str - optional (default: )

MIME type. Example: 'image/png'.


encryption     int8 - optional (default: 0)

Type of encryption. '0' means no encryption. '1' means AES-GCM encryption.


challenge     str[32] - optional

Hex coded 128-bit random number to be used in the signature. It is required for encrypted files.


signature     str[88] - optional

Hex coded 256-bit code of the encrypted output of challenge. It is required for encrypted files.


expiration_utime     int64 - optional (default: 576460752303423487)

Expiration time given in unix-time in microseconds. Default is 0x7ffffffffffffff.


tag     int64 - optional (default: 0)

Each bit defines a logical tag. This tag can be used as filter for get_entries.


expiration_count     int - optional (default: 0)

Short URL expires after this many number of clicks. Setting 0 disables the click-count-expiration.


host     str - optional (default: ww7.io)

Requested base host of shortened url. The available hosts are: ww7.io


code     str - optional

Provided to replace an existing shortened url or to use it if it does not belong to another used. Must be [6,16] in length, and contains only 26 letters in small and caps, and numbers.


shorturl     str - optional

Shortened url to be used. Ex: https://ww7.io/sD4fSa. If this parameter is provided, host and code parameters will be ignored.


qr     dict - optional

If provided, entry output returns 'qrcode' containing an image of the QR code of shortened link. The dictionary can have the following keys describing the format:

        format : Can be 'svg' or 'png'. Default: 'svg'
        border : Border around the QR code in background color. Default: 3
        fg : Foreground color. Default: '#000000' (black)
        bg : Background color. Default: '#ffffff' (white)
        level : Error correction level of QR code. Default: 'M'

Some or all key values can be omitted. Defaults will be used for the omitted values. (query['qr'] = {} yields an image completely formatted by the defaults.) Colors must be in #rrggbb or #rrggbbaa format. If aa (alpha) channel is given, transparency can be defined. 'level' can be L, M, Q, H representing the low, medium, quartile, high. Percentage of data that can be restored for each level is 7%, 15%, 25%, and 30% respectively.




OUTPUT ITEMS

entry     dictionary - always exists

Entry for the shortened URL pointing the file for download. Dictionary items are listed at get_entry





file_part_initialize

POST /v2/file_part_initialize



Weight: 1000


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


filename     str - required

Name of the file.


filesize     int64 - required

Size of the file in bytes.


filetype     str - optional (default: )

MIME type. Example: 'image/png'.




OUTPUT ITEMS

filekey     str[32] - always exists

A key pointing the stored file.


expiration_utime     int64 - always exists

Expiration time for the completion of upload. A slow connection speed is assumed.





file_part_upload

multi-form POST /v2/file_part_upload



Weight: 1250 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


filekey     str[32] - required

The key pointing to the stored file.


partnumber     int - required

Part number.


partsize     int - required

Size of the file part.




OUTPUT ITEMS




file_part_finalize

POST /v2/file_part_finalize



Weight: 1000


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


filekey     str - required

Key pointing the file to be stored.


encryption     int8 - optional (default: 0)

Type of encryption. '0' means no encryption. '1' means AES-GCM encryption.


challenge     str[32] - optional

Hex coded 128-bit random number to be used in the signature. It is required for encrypted files.


signature     str[88] - optional

Hex coded 48-byte code of the encrypted output of challenge. It is required for encrypted files.


expiration_utime     int64 - optional (default: 576460752303423487)

Expiration time given in unix-time in microseconds. Default is 0x7ffffffffffffff.


tag     int64 - optional (default: 0)

Each bit defines a logical tag. This tag can be used as filter for get_entries.


expiration_count     int - optional (default: 0)

Short URL expires after this many number of clicks. Setting 0 disables the click-count-expiration.


host     str - optional (default: ww7.io)

Requested base host of shortened url. The available hosts are: ww7.io


code     str - optional

Provided to replace an existing shortened url or to use it if it does not belong to another used. Must be [6,16] in length, and contains only 26 letters in small and caps, and numbers.


shorturl     str - optional

Shortened url to be used. Ex: https://ww7.io/sD4fSa. If this parameter is provided, host and code parameters will be ignored.


qr     dict - optional

If provided, entry output returns 'qrcode' containing an image of the QR code of shortened link. The dictionary can have the following keys describing the format:

        format : Can be 'svg' or 'png'. Default: 'svg'
        border : Border around the QR code in background color. Default: 3
        fg : Foreground color. Default: '#000000' (black)
        bg : Background color. Default: '#ffffff' (white)
        level : Error correction level of QR code. Default: 'M'

Some or all key values can be omitted. Defaults will be used for the omitted values. (query['qr'] = {} yields an image completely formatted by the defaults.) Colors must be in #rrggbb or #rrggbbaa format. If aa (alpha) channel is given, transparency can be defined. 'level' can be L, M, Q, H representing the low, medium, quartile, high. Percentage of data that can be restored for each level is 7%, 15%, 25%, and 30% respectively.




OUTPUT ITEMS

entry     dictionary - always exists

Entry for the shortened URL pointing the file for download. Dictionary items are listed at get_entry





change_shorturl

POST /v2/change_shorturl

Changes and existing shorturl.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


shorturl_old     str - required

Shortened url to be changed. Ex: https://ww7.io/sD4fSa


shorturl_new     str - required

Desired shortened url. Ex: https://ww7.io/fanciest




OUTPUT ITEMS




set_enabled

POST /v2/set_enabled

Sets the enabled state of shorturl to true or false. If set to false, the shorturl returns 404 Page not found code, but remains in the records, which can be enabled at a later time via this command.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


shorturl     str - required

Shortened url to be processed. Ex: https://ww7.io/sD4fSa


enabled     boolean - required

enabled state of the shorturl. If false, the shorturl returns 404 Page not found.




OUTPUT ITEMS




set_tag

POST /v2/set_tag

Changes the tag of shorturl.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


shorturl     str - required

Shortened url to be processed. Ex: https://ww7.io/sD4fSa


tag     int64 - required

Changes the TAG of short URL. Each bit defines a logical tag. This tag can be used as filter for get_entries.




OUTPUT ITEMS




set_expiration_count

POST /v2/set_expiration_count

Changes the expiration_count of the short URL.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


shorturl     str - required

Shortened url to be processed. Ex: https://ww7.io/sD4fSa


expiration_count     int64 - required

Changes expiration_count of the short URL.




OUTPUT ITEMS




delete

POST /v2/delete

Deletes an entry using its entryid.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


shorturl     str - required

Shortened url to be processed. Ex: https://ww7.io/sD4fSa




OUTPUT ITEMS




get_entry

POST /v2/get_entry

This function returns information about an entry. It may be for an URL or for a file.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


shorturl     str - required

Shortened url to be processed. Ex: https://ww7.io/sD4fSa


qr     dict - optional

If provided, entry output returns 'qrcode' containing an image of the QR code of shortened link. The dictionary can have the following keys describing the format:

        format : Can be 'svg' or 'png'. Default: 'svg'
        border : Border around the QR code in background color. Default: 3
        fg : Foreground color. Default: '#000000' (black)
        bg : Background color. Default: '#ffffff' (white)
        level : Error correction level of QR code. Default: 'M'

Some or all key values can be omitted. Defaults will be used for the omitted values. (query['qr'] = {} yields an image completely formatted by the defaults.) Colors must be in #rrggbb or #rrggbbaa format. If aa (alpha) channel is given, transparency can be defined. 'level' can be L, M, Q, H representing the low, medium, quartile, high. Percentage of data that can be restored for each level is 7%, 15%, 25%, and 30% respectively.




OUTPUT ITEMS

entry     dictionary - always exists

Dictionary containing the items of the entry:
        id : Unique ID of the entry.
        userid : User ID pointing the owner of the entry.
        url : Long URL or the filename.
        shorturl : Compressed short-url.
        utime : Creation time. Unix time in microseconds.
        tag : 64-bit tag.
        expiration_count : Click-count expiration limit.
        filekey : A unique ID for the file.
        filesize : Size of the file, if it is a file. "-1" for URLs.
        filetype : MIME type of the file, if it is a file. "-1" for URLs.
        encryption : Encryption type for a file. 0 means no encryption.
        signature : Signature to validate the password at client side.
        count : Number of clicks on the short-url.
        count_qr : Number of clicks/loads on the QR code url.
        order : 0.
        enabled : Flag (0/1) indicating if this entry is enabled.
        qrcode : QR code if requested. It is a dictionary with 'format', 'image', and 'encoding'





get_entries

POST /v2/get_entries

Gets a list of entries satisfying the requested TAG and order conditions. Entries are listed in reverse order according to their times of creation. start parameter is used where to start.As an example, if start=2 the list start with the second recent entry satisfying the TAG conditions.

Weight: 1000 per call + 100 per entry


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.


start     int - optional (default: 0)

Starting index of the list in the DB. '0' means the most recent. Increasing indices indicates further in the past.


qr     dict - optional

If provided, entry output returns 'qrcode' containing an image of the QR code of shortened link. The dictionary can have the following keys describing the format:

        format : Can be 'svg' or 'png'. Default: 'svg'
        border : Border around the QR code in background color. Default: 3
        fg : Foreground color. Default: '#000000' (black)
        bg : Background color. Default: '#ffffff' (white)
        level : Error correction level of QR code. Default: 'M'

Some or all key values can be omitted. Defaults will be used for the omitted values. (query['qr'] = {} yields an image completely formatted by the defaults.) Colors must be in #rrggbb or #rrggbbaa format. If aa (alpha) channel is given, transparency can be defined. 'level' can be L, M, Q, H representing the low, medium, quartile, high. Percentage of data that can be restored for each level is 7%, 15%, 25%, and 30% respectively.


count     int - optional (default: 3)

Number of entries requested. Maximum is 1000.


tagmask_or     int64 - optional

Selects only the entries with ANY of the tagmask_or.


tagmask_and     int64 - optional

Selects only the entries with ANY of the tagmask_and. If this is provided, tagmask_or is ignored.


tag     int64 - optional

Selects only the entries with tag If this is provided, tagmask_or and tagmask_and are ignored.




OUTPUT ITEMS

entries     list - always exists

List of dictionaries for the entries. Each of the entry items are defines in get_entry API call.





get_protected_file_info

POST /v2/get_protected_file_info

This function returns information required to receive the encrypted file, if 'challenge' provided correct. One still needs the file-password to decrypt the file. the 'challenge' can be found by decrypting the signature. And, the signature is provided via the redirected address of when the shortened URL is called.

Weight: 0


INPUT ITEMS

shorturl     str - required

Shortened url to be processed. Ex: https://ww7.io/sD4fSa


challenge     str[32] - required

Hex encoded 128-bit challenge, equals to decrypted signature.




OUTPUT ITEMS

filename     str - always exists

Name of the file.


filesize     int64 - always exists

Size of the file.


filetype     str - always exists

MIME type of the file.


url     str - always exists

URL of the encrypted file.


url_expire_utime     int64 - always exists

Expiration time of resource URL (given by 'url') in unix time in microseconds.


encryption     int8 - always exists

Type of the encryption. 0=No encryption, 1=AES-256 GCM.





get_signature

POST /v2/get_signature

This function returns information required to receive the encrypted file, if 'challenge' provided correct. One still needs the file-password to decrypt the file. the 'challenge' can be found by decrypting the signature. And, the signature is provided via the redirected address of when the shortened URL is called.

Weight: 0


INPUT ITEMS

shorturl     str - required

Shortened url to be processed. Ex: https://ww7.io/sD4fSa




OUTPUT ITEMS

signature     str[88] - always exists

Hex coded encrypted data of challenge. It is required for encrypted files. 12 bytes of IV, 16 bytes of encrypted challenge, 16 bytes of TAG for AES-GCM. Total of 44 bytes.





temporary_account

POST /v2/temporary_account

Creates a temporary account. It will have an expiration date. This is used for web interface, so user does not have to register to shorten an URL or upload a file, BEFORE registration. If the user registers at a later time, entries he/she created will be preserved with the account.

Weight: 1000 per call


INPUT ITEMS



OUTPUT ITEMS

userid     str[32] - always exists

Unique ID of the user.





signup

POST /v2/signup

Registers a user. Username is optional but email is required.

Weight: 1000 per call


INPUT ITEMS

email     str - required

E-mail address of the user.


password     str[64] - required

256 bit hex code of PBKDF2(password). SHA256 is the hashing function. 0x182c37f56e1967227ccae78af837b638 is the salt. Iterated 231581 times.


username     str - optional

Optional username for the account which can be used for login


userid     str[32] - optional

If a temporary account was used, the userid of the temporary account may be provided to convert that account to a 'registered' account. If that happens, the URLs and FILEs will be transferred to this registered account..




OUTPUT ITEMS

userid     str[32] - always exists

Unique ID of the user.


token     str[32] - always exists

A valid token which can be used when credentials are required.


email     str - always exists

E-mail address of the user.


username     str - exists if username is given during the registration

Username of the user.





login

POST /v2/login

Login to a registered account to get a valid token to be used for credentials.

Weight: 1000 per call


INPUT ITEMS

username_email     str - required

Username or e-mail address.


password     str[64] - required

256 bit hex code of PBKDF2(password). SHA256 is the hashing function. 0x182c37f56e1967227ccae78af837b638 is the salt. Iterated 231581 times.




OUTPUT ITEMS

userid     str[32] - always exists

Unique ID of the user.


token     str[32] - always exists

A valid token which can be used when credentials are required.


email     str - always exists

E-mail address of the user.


username     str[32] - exists if username is given during the registration

Username for the account.


email_verified     boolean - always exists

Shows whether the e-mail is verified.





logout

POST /v2/logout

Logout a user. This will invalidate the token provided.

Weight: 0


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required

Proof of credentials for a registered account. The token can be created with login API call.




OUTPUT ITEMS




change_password

POST /v2/change_password

Changes the account password for a registered account.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required

Proof of credentials for a registered account. The token can be created with login API call.


password     str[64] - required

256 bit hex code of PBKDF2 of CURRENT password. SHA256 is the hashing function. 0x182c37f56e1967227ccae78af837b638 is the salt. Iterated 231581 times.


password_new     str[64] - required

256 bit hex code of PBKDF2 of NEW password. SHA256 is the hashing function. 0x182c37f56e1967227ccae78af837b638 is the salt. Iterated 231581 times.




OUTPUT ITEMS




check_credentials

POST /v2/check_credentials

Checks if the userid is for a temporary account or userid/token pair is valid. Returns 'success' if credentials are valid.

Weight: 1000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.




OUTPUT ITEMS

email     str - always exists

E-mail address of the user.


username     str - exists if username is given during the registration.

Username of the user.


email_verified     boolean - always exists

Shows whether the e-mail is verified.





forgot_password

POST /v2/forgot_password

Initiates a password recovery process by sending an email to the registered email address of the account. The link embedded into the email will lead to a page to set a new password.

Weight: 5000


INPUT ITEMS

username_email     str - required

Username or e-mail address.




OUTPUT ITEMS




reset_password

POST /v2/reset_password

Resets the account password for a registered account. unique_code is sent to the registered email address, embedded into a shortlink. The unique_code has a short lifetime\ and expires after a grace period for this API to be called.

Weight: 5000 per call


INPUT ITEMS

email     str - required

E-mail address of the user.


password     str[64] - required

256 bit hex code of PBKDF2(password). SHA256 is the hashing function. 0x182c37f56e1967227ccae78af837b638 is the salt. Iterated 231581 times.


unique_code     str[32] - required

128 bit secret unique code sent to the email of the user.




OUTPUT ITEMS

userid     str[32] - always exists

Unique ID of the user.


token     str[32] - always exists

A valid token which can be used when credentials are required.


username     str[32] - exists if username is given during the registration

Username for the account.


email_verified     boolean - always exists

Shows whether the e-mail is verified.





verify_email

POST /v2/verify_email

Sends email verification message to the registered e-mail address. The e-mail contains a unique-link. Clicking on the link ensured that the e-mail is received by the user, and elevates the account to "verified" status. The link in the email is has a limited time of validity, and expires if not used.

Weight: 5000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required

Proof of credentials for a registered account. The token can be created with login API call.




OUTPUT ITEMS




get_account_info

POST /v2/get_account_info

This function returns information about the account.

Weight: 2000 per call


INPUT ITEMS

userid     str[32] - required

User ID identifying the user. This can be created with signup or temporary_account API calls, or can be reached via login API call for an existing registered account.


token     str[32] - required if userid is registered

Proof of credentials for a registered account. The token can be created with login API call. The validity duration depends on the account type; verified/registered/temporary.




OUTPUT ITEMS

type     str - always exists

Type of the account: temporary, registered, verified, custom,...


username     str[32] - exists if username is given during the registration

Username for the account.


email     str - exists if email is registered

E-mail address of the user.


email_verified     boolean - always exists

Shows whether the e-mail is verified.


type     str - always exists

Type of the account.


create_utime     int64 - always exists

Time of creation of the account. Type is unix-time is microseconds.


expiration_utime     int64 - always exists

Expiration time of the account. Type is unix-time is microseconds.


api_refill_rate     int - always exists

Refill rate of the bucket for the API call limiter.


api_capacity     int - always exists

Capacity of the bucket for the API call limiter.


api_balance     int - always exists

Remaining usable weight in the bucket for the API call limiter. It is the value before the cost of this call.


api_balance_utime     int - always exists

Time of last drop to the bucket for the API call limiter.


link_refill_rate     int - always exists

Refill rate of the bucket for the LINK usage limiter.


link_capacity     int - always exists

Capacity of the bucket for the LINK usage limiter.


link_balance     int - always exists

Remaining usable weight in the bucket for the LINK usage limiter.


link_balance_utime     int - always exists

Time of last drop to the bucket for the LINK usage limiter.





multi

POST /v2/multi

This function performs multiple API calls at once. The output of the calls can be routed to the input of the next call within the list of calls.

Weight: 0


INPUT ITEMS

call_queries     list - required

List of dictionaries. Each dictionary entry defines an API call and contains the following fields:

type : A String setting the type/name of the API call.
input : A dictionary containing the parameters of the API call.
broadcast : A boolean. If true, the output of the API call will be broadcast to the following API calls as input. Input parameter of the following API calls can overwrite these.




OUTPUT ITEMS

call_responses     list - always exists

List of dictionaries. Each dictionary is the response of the API calls listed in commands





Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
resp_login = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()

query = {
  "userid" : resp_login['output']['userid'],
  "token"  : resp_login['output']['token'],
  "url"    : "https://examle.com/",
  "tag"    : 0x8008,
}
response = requests.post("https://api.ww7io.com/v2/url", json.dumps(query)).json()


Query
{
  "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
  "token": "8hSdMgDzTDXNW0Texqbq7JDcH5hOE0Z4",
  "url": "https://example.com/",
  "tag": 32776
}


Response
{
  "output": {
    "entry": {
      "count": 0,
      "count_qr": 0,
      "enabled": false,
      "encryption": 0,
      "filekey": "",
      "filesize": -1,
      "filetype": "",
      "id": 3576066480,
      "order": 0,
      "shorturl": "https://ww7.io/D4AyPm",
      "signature": "",
      "tag": 32776,
      "url": "https://example.com/",
      "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
      "utime": 1663520979909818
    }
  },
  "status": "success",
  "type": "url",
  "utime": 1660552794085981,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"
urls = [
  "https://en.wikipedia.org", 
  "https://youtube.com", 
  "https://amazon.com", 
  "https://facebook.com", 
  "https://twitter.com"
]


query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
  "userid" : response['output']['userid'],
  "token"  : response['output']['token'],
  "tag"    : 0x8008,
  "urls"   : urls,
}
response = requests.post("https://api.ww7io.com/v2/urls", json.dumps(query)).json()


Query
{
  "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
  "token": "JMi3pNCQDRbI0CiAqrywCuwYraEmLGrz",
  "tag": 32776,
  "urls": [
    "https://en.wikipedia.org",
    "https://youtube.com",
    "https://amazon.com",
    "https://facebook.com",
    "https://twitter.com"
  ]
}


Response
{
  "output": {
    "entries": [
      {
        "count": 0,
        "count_qr": 0,
        "enabled": false,
        "encryption": 0,
        "filekey": "",
        "filesize": -1,
        "filetype": "",
        "id": 36754020030,
        "order": 0,
        "shorturl": "https://ww7.io/oHWHkq",
        "signature": "",
        "tag": 32776,
        "url": "https://en.wikipedia.org",
        "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
        "utime": 1663521279040727
      },
      {
        "count": 0,
        "count_qr": 0,
        "enabled": false,
        "encryption": 0,
        "filekey": "",
        "filesize": -1,
        "filetype": "",
        "id": 17735361113,
        "order": 0,
        "shorturl": "https://ww7.io/TWPvlf",
        "signature": "",
        "tag": 32776,
        "url": "https://youtube.com",
        "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
        "utime": 1663521279040728
      },
      {
        "count": 0,
        "count_qr": 0,
        "enabled": false,
        "encryption": 0,
        "filekey": "",
        "filesize": -1,
        "filetype": "",
        "id": 22213009860,
        "order": 0,
        "shorturl": "https://ww7.io/YPRgkk",
        "signature": "",
        "tag": 32776,
        "url": "https://amazon.com",
        "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
        "utime": 1663521279040729
      },
      {
        "count": 0,
        "count_qr": 0,
        "enabled": false,
        "encryption": 0,
        "filekey": "",
        "filesize": -1,
        "filetype": "",
        "id": 33860490823,
        "order": 0,
        "shorturl": "https://ww7.io/k7hKcv",
        "signature": "",
        "tag": 32776,
        "url": "https://facebook.com",
        "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
        "utime": 1663521279040730
      },
      {
        "count": 0,
        "count_qr": 0,
        "enabled": false,
        "encryption": 0,
        "filekey": "",
        "filesize": -1,
        "filetype": "",
        "id": 21768134979,
        "order": 0,
        "shorturl": "https://ww7.io/XvK2TR",
        "signature": "",
        "tag": 32776,
        "url": "https://twitter.com",
        "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
        "utime": 1663521279040731
      }
    ]
  },
  "status": "success",
  "type": "urls",
  "utime": 1663521279040727,
  "weight": 1500
}

Python Example

import requests, json, hashlib
import mimetypes, os, secrets
from Crypto.Cipher import AES


#
# Encrypt data
#
def encrypt_data(data, password):
	#
	# 256-bit key is double-sha256 of file password
	#
	key = hashlib.sha256(hashlib.sha256(password.encode()).digest()).digest()

	#
	# Encrypt data
	#
	iv = secrets.token_bytes(12)
	cipher = AES.new(key, AES.MODE_GCM, nonce=iv, mac_len=16)
	data_encrypted, tag = cipher.encrypt_and_digest(data)

	return iv+data_encrypted+tag


#
# Encrypt data, generate challenge-signature pair
#
def encrypt_file(rawdata, password):
	challenge = secrets.token_bytes(16)
	signature = encrypt_data(challenge, password)
	rawdata   = encrypt_data(rawdata  , password)
	return int.to_bytes(len(rawdata),4,'little')+rawdata, challenge.hex(), signature.hex()



username = "Test User"
password = "Trial151!"

query = {
	"username_email" : username,
	"password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
resp_login = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


filename = "sample-image.png"
filesize = os.stat(filename).st_size
filetype,_ = mimetypes.guess_type(filename)

file = open(filename, 'rb')
rawdata = file.read()
file.close()


query = {
	"userid"     : resp_login['output']['userid'],
	"token"      : resp_login['output']['token'],
	"filename"   : filename,
	"filesize"   : filesize,
	"filetype"   : filetype,
}


encrypt = True
if encrypt:
	filepassword = "TestPassword"
	rawdata, challenge, signature = encrypt_file(rawdata, filepassword)
	query['challenge'] = challenge
	query['signature'] = signature
	query['encryption'] = 1


files = {
	"query": (None, json.dumps(query), 'application/json'),
	filename: (filename, rawdata, filetype)
}
response = requests.post("https://api.ww7io.com/v2/file", files=files).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "TZ1Tk6Um00ZGxSbe0Iluw4IpJaeAdRxd",
  "filename": "sample-image.png",
  "filesize": 53990,
  "filetype": "image/png",
  "challenge": "284932ca2ea3595cf6d106ef51ca3826",
  "signature": "8d0734a61bc0cc213c062f3a95a01c751a4fe5f2f99e55285e24bcb459b10441a5d8aa012338edea2978b467",
  "encryption": 1
}


Response
{
  "output": {
    "entry": {
      "count": 0,
      "count_qr": 0,
      "enabled": false,
      "encryption": 1,
      "filekey": "LcZJXWn7nYxUFTxzsJ9pDWTDZKF8IFXc",
      "filesize": 53990,
      "filetype": "image/png",
      "id": 39155848098,
      "order": 0,
      "shorturl": "https://ww7.io/qt36xE",
      "signature": "8d0734a61bc0cc213c062f3a95a01c751a4fe5f2f99e55285e24bcb459b10441a5d8aa012338edea2978b467",
      "tag": 0,
      "url": "sample-image.png",
      "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
      "utime": 1663522311008072
    }
  },
  "status": "success",
  "type": "file",
  "utime": 1663522311008072,
  "weight": 1000
}

Python Example




Query



Response


Python Example




Query



Response


Python Example




Query



Response


Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
    "username_email" : username,
    "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
    "userid" : response['output']['userid'],
    "token"  : response['output']['token'],
    "url"    : 'https://www.example.com/',
}
url_response = requests.post("https://api.ww7io.com/v2/url", json.dumps(query)).json()


query = {
    "userid"       : response['output']['userid'],
    "token"        : response['output']['token'],
    "shorturl_old" : url_response['output']['entry']['shorturl'],
    "shorturl_new" : "https://ww7.io/fanciest",
}
response = requests.post("https://api.ww7io.com/v2/change_shorturl", json.dumps(query)).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "r1PXIK0ss3eJYOSPw8wOl7s5KJHJ3ZLl",
  "shorturl_old": "https://ww7.io/RvE1ga",
  "shorturl_new": "https://ww7.io/fanciest"
}


Response
{
  "output": {},
  "status": "success",
  "type": "change_shorturl",
  "utime": 1663587014412020,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
    "username_email" : username,
    "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
    "userid" : response['output']['userid'],
    "token"  : response['output']['token'],
    "url"    : "https://www.example.com",
}
url_response = requests.post("https://api.ww7io.com/v2/url", json.dumps(query)).json()


query = {
    "userid"   : response['output']['userid'],
    "token"    : response['output']['token'],
    "shorturl" : url_response['output']['entry']['shorturl'],
    "enabled"  : False,
}
response = requests.post("https://api.ww7io.com/v2/set_enabled", json.dumps(query)).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "zxYYvzcxxQqJh7NhbIfMXFvmgwFOTVE8",
  "shorturl": "https://ww7.io/bkQoqx",
  "enabled": false
}


Response
{
  "output": {},
  "status": "success",
  "type": "set_enabled",
  "utime": 1663589372873185,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
    "username_email" : username,
    "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
    "userid" : response['output']['userid'],
    "token"  : response['output']['token'],
    "url"    : "https://www.example.com",
}
url_response = requests.post("https://api.ww7io.com/v2/url", json.dumps(query)).json()


query = {
    "userid"   : response['output']['userid'],
    "token"    : response['output']['token'],
    "shorturl" : url_response['output']['entry']['shorturl'],
    "tag"      : 0x123456789a,
}
response = requests.post("https://api.ww7io.com/v2/set_tag", json.dumps(query)).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "zxYYvzcxxQqJh7NhbIfMXFvmgwFOTVE8",
  "shorturl": "https://ww7.io/bkQoqx",
  "enabled_state": false
}


Response
{
  "output": {},
  "status": "success",
  "type": "set_tag",
  "utime": 1663589372873185,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
    "username_email" : username,
    "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
    "userid" : response['output']['userid'],
    "token"  : response['output']['token'],
    "url"    : "https://www.example.com",
}
url_response = requests.post("https://api.ww7io.com/v2/url", json.dumps(query)).json()


query = {
    "userid"           : response['output']['userid'],
    "token"            : response['output']['token'],
    "shorturl"         : url_response['output']['entry']['shorturl'],
    "expiration_count" : 100,
}
response = requests.post("https://api.ww7io.com/v2/set_expiration_count", json.dumps(query)).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "zxYYvzcxxQqJh7NhbIfMXFvmgwFOTVE8",
  "shorturl": "https://ww7.io/bkQoqx",
  "expiration_count": false
}


Response
{
  "output": {},
  "status": "success",
  "type": "expiration_count",
  "utime": 1663589372873185,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
    "username_email" : username,
    "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
    "userid" : response['output']['userid'],
    "token"  : response['output']['token'],
    "url"    : "https://www.example.com",
}
url_response = requests.post("https://api.ww7io.com/v2/url", json.dumps(query)).json()


query = {
    "userid"   : response['output']['userid'],
    "token"    : response['output']['token'],
    "shorturl" : url_response['output']['entry']['shorturl'],
}
response = requests.post("https://api.ww7io.com/v2/delete", json.dumps(query)).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "e4RdQC0Kb1EpZOAnuJf08ohIZhjJ9y1y",
  "shorturl": "https://ww7.io/l4K2IW"
}


Response
{
  "output": {},
  "status": "success",
  "type": "delete",
  "utime": 1663522151493030,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
    "username_email" : username,
    "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
    "userid" : response['output']['userid'],
    "token"  : response['output']['token'],
    "url"    : "https://www.example.com/"
}
url_response = requests.post("https://api.ww7io.com/v2/url", json.dumps(query)).json()


query = {
    "userid"   : response['output']['userid'],
    "token"    : response['output']['token'],
    "shorturl" : url_response['output']['entry']['shorturl'],
}
response = requests.post("https://api.ww7io.com/v2/get_entry", json.dumps(query)).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "K19p9EUWo1L9A6fvIi6Vf42AVRAk4ReO",
  "shorturl": "https://ww7.io/22NXsM"
}


Response
{
  "output": {
    "entry": {
      "count": 0,
      "count_qr": 0,
      "enabled": false,
      "encryption": 0,
      "filekey": "",
      "filesize": -1,
      "filetype": "",
      "id": 50272284488,
      "order": 0,
      "shorturl": "https://ww7.io/22NXsM",
      "signature": "",
      "tag": 0,
      "url": "https://www.example.com/",
      "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
      "utime": 1663521639011671
    }
  },
  "status": "success",
  "type": "get_entry",
  "utime": 1663521639395699,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
    "username_email" : username,
    "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
    "userid" : response['output']['userid'],
    "token"  : response['output']['token'],
    "count"  : 2,
    "start"  : 1,
    "qr"     : {'format': 'png', 'bg': '#ffffff00', 'fg': '#4444aa', 'level': 'M', 'border': 1},
}
response = requests.post("https://api.ww7io.com/v2/get_entries", json.dumps(query)).json()


Query
{
  "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
  "token": "8wCbxKAII1JvFFbkv7mE3uTJWGKRNqSH",
  "count": 2,
  "start": 1,
  "qr": {
    "format": "png",
    "bg": "#ffffff00",
    "fg": "#4444aa",
    "level": "M",
    "border": 1
  }
}


Response
{
  "output": {
    "entries": [
      {
        "count": 0,
        "count_qr": 0,
        "enabled": false,
        "encryption": 0,
        "filekey": "",
        "filesize": -1,
        "filetype": "",
        "id": 13123367331,
        "order": 1,
        "qrcode": {
          "encoding": "base64",
          "format": "png",
          "image": "iVBORw0KGgoAAAANSUhEUgAAAQ4AAAEOAQMAAABCf2vmAAAABlBMVEX///9ERKqARzaVAAAAAnRSTlMA/1uRIrUAAAFJSURBVHic7djJDYQwDAVQSxSQktI6JaUAJA/xlsBhJGK4fR8Qy9McHI8xIUJ8GZUtqDYi3mnrZ5vfbSAp0iTJ54NIthC7BEmSnuy417Gtgi8KyBuk8kFyBvIFOS/P00PvgbxDrKhlAewQ1Q6SJP6Ks7T7wQIkRUZYodOfAHlIrh2E93L2571I8o/5HwCyQrRviJMaHx2kvwd3AsmQ6n1jyn1/oA2FQFIkFmDMFhRz8W2NQJ4TWwW9x1rUfayQDtJAMkRy3yvbRjUp73L4AwLJENuF8BmYijXke/MAWSVSxXydI/yzGSRDdAPCk+3zmoX+BsgyGTF/zlEsBUiG1Ei2zhbMswNJEj3bory9g9TxDwBZJ9aGL19yEQ3kHdLnNRvayD84QF4jU40Ljq0IkHUSzaPEpoTknplBssQu7MUXGz0UszLIOkF8Fz8/MxTsIxIO0QAAAABJRU5ErkJggg=="
        },
        "shorturl": "https://ww7.io/OUITVB",
        "signature": "",
        "tag": 0,
        "url": "https://www.example.com/",
        "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
        "utime": 1663521619955946
      },
      {
        "count": 0,
        "count_qr": 0,
        "enabled": false,
        "encryption": 0,
        "filekey": "",
        "filesize": -1,
        "filetype": "",
        "id": 29773207503,
        "order": 2,
        "qrcode": {
          "encoding": "base64",
          "format": "png",
          "image": "iVBORw0KGgoAAAANSUhEUgAAAQ4AAAEOAQMAAABCf2vmAAAABlBMVEX///9ERKqARzaVAAAAAnRSTlMA/1uRIrUAAAFASURBVHic7dlbDoMgEAXQSVgAS+rWWRILaDKVeYDaRyqDf3c+jNbjz0AuaIlQd9aDrYjys122Q03+awUJkSpNTqx39Wwj1nuQIGnNrkJYz8YlyDpS9x0HWUtaeDgGWUU8PPSQ+Ue+gFwlbGVt94MVSIiMsolOdL4BMk1224pqc5xLZp3oXEBCxNKCeipvZ0VCmkHCRDfC4uRdg0c9yfMFZJbo9Lah2Dqe7G6RtzuQEJHej81EHwV9CiRGZLkrZJFBFs1tAOQ3AokS36VZWryHB8g06SudnI0ByPvXOZBp4gsfs+8jWtX0FjIgF8kobTZ/WBFBZsnDo0KuDlk8HgOZJdrn/o3nGMgMEiSpB8XpG4/cAFlE+qatpzLIUmKbNpny+es3eJD/CWnbteOF0jlBQALEs4JOn3z0P3qQEEHdVy9V+CoEpLtnJAAAAABJRU5ErkJggg=="
        },
        "shorturl": "https://ww7.io/ge5VWP",
        "signature": "",
        "tag": 0,
        "url": "https://www.example.com/",
        "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
        "utime": 1663521591087993
      }
    ]
  },
  "status": "success",
  "type": "get_entries",
  "utime": 1663521886987508,
  "weight": 1200
}

Python Example

import requests, json, hashlib
import mimetypes, os, secrets, sys
from Crypto.Cipher import AES




#
# Encrypt data
#
def encrypt_data(data, password):
    #
    # 256-bit key is double-sha256 of file password
    #
    key = hashlib.sha256(hashlib.sha256(password.encode()).digest()).digest()

    #
    # Encrypt data
    #
    iv = secrets.token_bytes(12)
    cipher = AES.new(key, AES.MODE_GCM, nonce=iv, mac_len=16)
    data_encrypted, tag = cipher.encrypt_and_digest(data)

    return iv + data_encrypted + tag




#
# Encrypt data
#
def decrypt_data(data, password):
    #
    # 256-bit key is double-sha256 of file password
    #
    key = hashlib.sha256(hashlib.sha256(password.encode()).digest()).digest()

    #
    # Encrypt data
    #
    iv = data[:12]
    tag = data[-16:]
    cipher = AES.new(key, AES.MODE_GCM, nonce=iv, mac_len=16)
    try:
        data_decrypted = cipher.decrypt_and_verify(data[12:-16],tag)
    except:
        print('Incorrect password or corrupted data.')
        sys.exit()

    return data_decrypted




#
# Encrypt data, generate challenge-signature pair
#
def encrypt_file(rawdata, password):
    challenge = secrets.token_bytes(16)
    signature = encrypt_data(challenge, password)
    rawdata   = encrypt_data(rawdata  , password)
    return int.to_bytes(len(rawdata),4,'little')+rawdata, challenge.hex(), signature.hex()




#
# Some input information
#
username = "Test User"
password = "Trial151!"
filepassword = 'TestPassword'

#
# Log in to get userid and token
#
query = {
    "username_email": username,
    "password": hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response_login = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()

#
# Put a file with encryption and get host and code for the short link
#
filename = "sample-image.png"
filesize = os.stat(filename).st_size
filetype, _ = mimetypes.guess_type(filename)

file = open(filename, 'rb')
rawdata = file.read()
file.close()

rawdata, challenge, signature = encrypt_file(rawdata, filepassword)

query = {
    "userid": response_login['output']['userid'],
    "token": response_login['output']['token'],
    "filename": filename,
    "filesize": filesize,
    "filetype": filetype,
    "tag": 1000,
    "challenge": challenge,
    "signature": signature,
    "encryption": 1,
}

files = {
    "query": (None, json.dumps(query), 'application/json'),
    filename: (filename, rawdata, filetype)
}
response_file = requests.post("https://api.ww7io.com/v2/file", files=files).json()

#
# Get signature for the file accessed by the short link, and resolve the challenge word
#
query = {
    "shorturl": response_file['output']['entry']['shorturl'],
}

response_get_signature = requests.post("https://api.ww7io.com/v2/get_signature", json.dumps(query)).json()

#
# Find the challenge using the file-password and encoded signature
#
signature = bytes.fromhex(response_get_signature['output']['signature'])
challenge = decrypt_data(signature, filepassword).hex()

#
# Get the protected file information for download
#
query = {
    "shorturl": response_file['output']['entry']['shorturl'],
    "challenge": challenge,
}
response_get_protected_file_info = requests.post("https://api.ww7io.com/v2/get_protected_file_info", json.dumps(query)).json()

#
# Download & Decrypt & Write the file
#
rawdata = requests.get(response_get_protected_file_info['output']['url']).content
if int.from_bytes(rawdata[:4],'little') != (len(rawdata)-4):
    print('Length of data is incorrect.')
    sys.exit()

rawdata = decrypt_data(rawdata[4:], filepassword)
file = open('downloaded-' + response_get_protected_file_info['output']['filename'], 'wb')
file.write(rawdata)


print("
Query")
print(json.dumps(query, indent=2))
print("
")

print("
Response")
print((json.dumps(response_get_protected_file_info, indent=2, ensure_ascii=False).encode('utf8')).decode())
print("
")


Query
{
  "shorturl": "https://ww7.io/I9QCOI",
  "challenge": "3fecf0b18bfc0188d015a6b35a84c733"
}


Response
{
  "output": {
    "encryption": 1,
    "filename": "sample-image.png",
    "filesize": 53990,
    "filetype": "image/png",
    "url": "https://ww7.s3.amazonaws.com/storage/fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf/R1mko0hpt6zbS0GrpYCGmzLU0UgBgzYq/sample-image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAUNQIG5VL4CMTG3UM%2F20220918%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20220918T174157Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host&X-Amz-Signature=e95d32c5548b72041ad80698c37bc4332c65939807b39414d5e980e914bd2bf8",
    "url_expire_utime": 1663522977091225
  },
  "status": "success",
  "type": "get_protected_file_info",
  "utime": 1663522917091225
}

Python Example

import requests, json

query = {
	"shorturl" : "https://ww7.io/qt36xE",
}

response = requests.post("https://api.ww7io.com/v2/get_signature", json.dumps(query)).json()


Query
{
  "shorturl": "https://ww7.io/qt36xE"
}


Response
{
  "output": {
    "signature": "8d0734a61bc0cc213c062f3a95a01c751a4fe5f2f99e55285e24bcb459b10441a5d8aa012338edea2978b467"
  },
  "status": "success",
  "type": "get_signature",
  "utime": 1663522523067399
}

Python Example

import requests, json

response = requests.post("https://api.ww7io.com/v2/temporary_account", "{}").json()


Query
{
}


Response
{
  "output": {
    "userid": "IMfmSN5ybU40gQ8qnIfX50SR8BlIeeY9"
  },
  "status": "success",
  "type": "temporary_account",
  "utime": 1660583286087677,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
email    = "test.user@nowhere.com"
password = "Trial151!"

query = {
  "email"    : email,
  "username" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}

response = requests.post("https://api.ww7io.com/v2/signup", json.dumps(query)).json()


Query
{
    "email": "test.user@nowhere.com",
    "username": "Test User",
    "password": "ffbbafe935a9c961cc5ea6bbdb8d994e3eb2c84f8a48f998fcef14feb9cc1bde"
}


Response
{
    "output": {
        "email": "test.user@nowhere.com",
        "token": "tMf1V94fN9dCh3X8mFA5yeRebh1MtUx9",
        "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
        "username": "Test User"
    },
    "status": "success",
    "type": "signup",
    "utime": 1660552435810099,
    "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}

response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


Query
{
  "username_email": "Test User",
  "password": "ffbbafe935a9c961cc5ea6bbdb8d994e3eb2c84f8a48f998fcef14feb9cc1bde"
}


Response
{
  "output": {
    "email": "test.user@nowhere.com",
    "token": "dbxLnxqGypFKM41CkoEYlvliscI16lNF",
    "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
    "username": "Test User"
  },
  "status": "success",
  "type": "login",
  "utime": 1660583738157707,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
  "userid" : response['output']['userid'],
  "token" : response['output']['token'],
}
response = requests.post("https://api.ww7io.com/v2/logout", json.dumps(query)).json()


Query
{
  "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
  "token": "RH4r8jGM9It7DUxucur0Y3kCnF20wLhk"
}


Response
{
  "output": {},
  "status": "success",
  "type": "logout",
  "utime": 1660583822273985,
  "weight": 0
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"
password_new = "NewPassword12!"

query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
  "userid"       : response['output']['userid'],
  "token"        : response['output']['token'],
  "password"     : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
  "password_new" : hashlib.sha256(hashlib.sha256(password_new.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/change_password", json.dumps(query)).json()


Query
{
  "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
  "token": "2yBgOKq1hRz6LEEwRVlQulS7gLv87jQC",
  "password": "ffbbafe935a9c961cc5ea6bbdb8d994e3eb2c84f8a48f998fcef14feb9cc1bde",
  "password_new": "ba74bcfc739dada58d1a7b0c87c4488fce5453ad7cb6b4077a0c97e52233ab92"
}


Response
{
  "output": {},
  "status": "success",
  "type": "change_password",
  "utime": 1660583911451820,
  "weight": 1000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
  "userid" : response['output']['userid'],
  "token"  : response['output']['token'],
}
response = requests.post("https://api.ww7io.com/v2/check_credentials", json.dumps(query)).json()


Query
{
  "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
  "token": "Dj54y75Xim4oUBj3wFEDSLtHDFWpExrV"
}


Response
{
  "output": {
    "email": "test.user@nowhere.com",
    "username": "Test User"
  },
  "status": "success",
  "type": "check_credentials",
  "utime": 1660584073484124,
  "weight": 1000
}

Python Example

import requests, json

username = "Test User"

query = {
	"username_email" : username,
}

response = requests.post("https://api.ww7io.com/v2/forgot_password", json.dumps(query)).json()


Query
{
  "username_email": "Test User"
}


Response
{
  "output": {},
  "status": "success",
  "type": "forgot_password",
  "utime": 1661018749011548,
  "weight": 5000
}

Python Example

import requests, json, hashlib

unique_code = "9f0c48d2bb15d09b12e7881869b570bc"
email       = "test.user@nowhere.com"
password    = "ResetNew121!"

query = {
	"unique_code" : unique_code,
	"email"       : email,
	"password"    : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}

response = requests.post("https://api.ww7io.com/v2/reset_password", json.dumps(query)).json()


Query
{
  "unique_code": "f4c64ad2e589e6218003f57e042c0c67",
  "email": "test.user@nowhere.com",
  "password": "c063ce91280773e47a895f3405d75625eb9e60c38522937976f3a20a6856e940"
}


Response
{
  "output": {
    "email_verified": false,
    "token": "hlrHGDCENqFksdt1gm38pQ9ScKcMUu9n",
    "userid": "fCvQf6k7w8JLKWfPuVTA0sybeKHNNQGf",
    "username": "Test User"
  },
  "status": "success",
  "type": "reset_password",
  "utime": 1663517025423038,
  "weight": 5000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
  "userid"       : response['output']['userid'],
  "token"        : response['output']['token'],
}
response = requests.post("https://api.ww7io.com/v2/verify_email", json.dumps(query)).json()


Query
{
  "userid": "FeJr3QgHeHe9D0kAxBBBo9lBidVhrRaU",
  "token": "2yBgOKq1hRz6LEEwRVlQulS7gLv87jQC",
}


Response
{
  "output": {},
  "status": "success",
  "type": "verify_email",
  "utime": 1660583911451820,
  "weight": 5000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
  "username_email" : username,
  "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
}
response = requests.post("https://api.ww7io.com/v2/login", json.dumps(query)).json()


query = {
  "userid" : response['output']['userid'],
  "token"  : response['output']['token'],
}
response = requests.post("https://api.ww7io.com/v2/get_account_info", json.dumps(query)).json()


Query
{
  "userid": "Xf9qa6Zp35bIphTDHPklBf8XgP6JcFed",
  "token": "U7YGYmxQGpL7intHq2Jc09ZHPLvcfx4m"
}


Response
{
  "output": {
    "api_balance": 120000,
    "api_balance_utime": 1660756113933003,
    "api_capacity": 120000,
    "api_refill_rate": 2000,
    "create_utime": 1660741579885868,
    "email": "test.user@nowhere.com",
    "expiration_utime": 9223372036854775807,
    "link_balance": 120000,
    "link_balance_utime": 1660756113933003,
    "link_capacity": 129600000000,
    "link_refill_rate": 50000,
    "type": "registered",
    "username": "Test User"
  },
  "status": "success",
  "type": "get_account_info",
  "utime": 1660756113933003,
  "weight": 2000
}

Python Example

import requests, json, hashlib

username = "Test User"
password = "Trial151!"

query = {
  "call_queries" : [
    {
      "type": "login",
      "broadcast": True,
      "input":
        {
          "username_email" : username,
          "password" : hashlib.sha256(hashlib.sha256(password.encode()).digest()).hexdigest(),
        },
    },

    {
      "type": "get_entries",
      "input":
        {
          "count"  : 2,
          "start"  : 1,
          "qr"     : False,
        },
    },

  ],

}

response = requests.post("https://api.ww7io.com/v2/multi", json.dumps(query)).json()


Query
{
  "call_queries": [
    {
      "type": "login",
      "broadcast": true,
      "input": {
        "username_email": "Test User",
        "password": "ffbbafe935a9c961cc5ea6bbdb8d994e3eb2c84f8a48f998fcef14feb9cc1bde"
      }
    },
    {
      "type": "get_entries",
      "input": {
        "count": 2,
        "start": 1
      }
    }
  ]
}


Response
{
  "output": {
    "call_responses": [
      {
        "output": {
          "email": "test.user@nowhere.com",
          "token": "NWPVOkxa2tu2kDIFdwuytR53JsvQBATN",
          "userid": "UC8IgEUjMffEmvQV5eEPKNV1sOKa7TLg",
          "username": "Test User"
        },
        "status": "success",
        "type": "login",
        "utime": 1660860580548188,
        "weight": 1000
      },
      {
        "output": {
          "entries": [
            {
              "code": "7GeTCV",
              "count": 0,
              "count_qr": 0,
              "encryption": 0,
              "filesize": -1,
              "filetype": "",
              "host": "ww7.io",
              "id": 54147718125,
              "order": 1,
              "tag": 32776,
              "url": "https://facebook.com",
              "url_compressed": "https://ww7.io/7GeTCV",
              "userid": "UC8IgEUjMffEmvQV5eEPKNV1sOKa7TLg",
              "utime": 1660860557531178
            },
            {
              "code": "luMXcJ",
              "count": 0,
              "count_qr": 0,
              "encryption": 0,
              "filesize": -1,
              "filetype": "",
              "host": "ww7.io",
              "id": 34579576333,
              "order": 2,
              "tag": 32776,
              "url": "https://amazon.com",
              "url_compressed": "https://ww7.io/luMXcJ",
              "userid": "UC8IgEUjMffEmvQV5eEPKNV1sOKa7TLg",
              "utime": 1660860557531177
            }
          ]
        },
        "status": "success",
        "type": "get_entries",
        "utime": 1660860580548188,
        "weight": 1200
      }
    ]
  },
  "status": "success",
  "type": "multi",
  "utime": 1660860580548188
}