UDP API Definition: Difference between revisions
mNo edit summary |
Epoximator (talk | contribs) |
||
Line 917: | Line 917: | ||
=== PING: Ping Command === | === PING: Ping Command === | ||
'''Command String:''' | '''Command String:''' | ||
* PING | * PING [nat=1] | ||
'''Possible Replies:''' | '''Possible Replies:''' | ||
* 300 PONG | * 300 PONG | ||
: {int4 port} ''(when nat=1)'' | |||
'''Info:''' | '''Info:''' | ||
* May be used by a frontend to determine if the API is still available. | * May be used by a frontend to determine if the API is still available. | ||
* May be executed even if not yet logged in. | * May be executed even if not yet logged in. | ||
* The option <tt>nat=1</tt> provides an easy way to determine if the router has changed the outgoing port. ([http://tracker.anidb.info/view.php?id=587 587]) | |||
---- | ---- |
Revision as of 08:59, 15 April 2007
General Information
Author: Exp & Epoximator
Version: 0.03b - 23.07.2006
Version number used for protover parameter: "3"
IMPORTANT NOTICE FOR DEVELOPERS:
- If you want to create a client you have to register it here and here.
- Check out the clients that are being developed. There exists usable code in many different languages already.
- If you have suggestions for improvements or new features use the development page.
- If you want to receive a notification mail every time a new version of the API Specs is released send an email to anidb.udp.api-request@freelists.org with subscribe as the subject.
Formats used in this Spec
- {vartype varname} - Specifies what shall be inserted at this point and its type.
- [...] - Everything between [ and ] is optional.
Used types
- int2 - 2 byte Integer (in string representation)
- int4 - 4 byte Integer (in string representation)
- str - String (NOTE: might be as long as 5000 bytes !!!, but via udp api never extend 1400 bytes)
Content Encoding
- Default character encoding: ASCII
- Escape scheme for option values (to server): html form encoding + newline
- This means you have to encode at least & in your option values in html form encoding style (&) before sending them to the api server. All other html form encodings are optional.
- All newlines should be replaced by <br />
- Escape scheme for returned data fields (from server): ', | and newline
- Newlines are encoded as <br />, ' is encoded as ` and | is not allowed in data fields.
Basics
General
{three digit return code} {str return string}\n {data field 0}|{data field 1}|...|{data field n}\n
The network communication is packet and line based. Each ANIDB API command is exactly one UDP packet containing one line. Results are sent as one packet but may consist out of multiple lines. A return value always starts with a 3 byte result code followed by a human redable version of the result code. Be aware that important data fields may be returned directly after the return code (see: 200,201,271,272,504). The meaning for all result codes can be found in this document. If there is more than one entry returned, it's one entry per line. Lines are terminated by a \n (no dos linefeed \r). The elements of a format string are seperated by a "|" character.
IMPORTANT:
- All commands except PING requires login, meaning that the session tag must be set (s=xxxxx).
- A client should ignore any additional trailing data fields it doesn't expect. Additional fields are going to be added to the output of some commands from time to time. Those additional fields will simply be appended to the end of the existing output. A client should be written in a way so that it is not affected by such new fields.
- Due to the length constraints of an UDP package the replies from the server will never exceed 1400 bytes. String fields will be truncated if necessary to ensure this. No warnings are given when this happens.
- A client should handle all possible return codes for each command.
- Possible return codes for all commands:
- 505 ILLEGAL INPUT OR ACCESS DENIED
- 555 BANNED
- {str reason}
- 598 UNKNOWN COMMAND
- 600 INTERNAL SERVER ERROR
- 601 ANIDB OUT OF SERVICE - TRY AGAIN LATER
- 602 SERVER BUSY - TRY AGAIN LATER
- Additional return codes for all commands that require login:
- 501 LOGIN FIRST
- 502 ACCESS DENIED
- 506 INVALID SESSION
- Possible return codes for all commands:
NOTE: | The '555 BANNED' message should not be expected by the client. This message is only enabled temporary to help developers understand what they are doing wrong. |
NOTE: | While in daily maintenance the AniDB API will reply with
601 ANIDB OUT OF SERVICE - TRY AGAIN LATER to all commands. If a client recieves such a return value it should wait at least 30 minutes before trying again. |
Server / UDP Connection
The Client has to send data packets to:
- Server: api.anidb.info
- Port: 9000/UDP
The servername and port should not be hardcoded into a frontend but should be read from a configuration file.
Server Errors
- At any time the API might return a fatal error of the form:
- 6xx ERROR DESCRIPTION
- Possible codes are 600-699.
- Occurances of these errors (except 601) should be reported to epoximator.
NOTE: | 6XX messages do not always return the tags given with the command which caused the error! |
Connection Problems
There are many ways for a client to end up banned or the API might currently be handling too many concurrent connections. If a client does not get any reply to an AUTH command it should start to increase the retry delay exponentially with every failed login attempt. (i.e. try again after 30 seconds if the first login attempt failed, if the second fails too retry after 2 minutes, then 5 minutes, then 10 minutes, then 30 minutes, ... until you reach a retry delay of ~2-4h.)
Local Port
A client should select a fixed local port >1024 at install time and reuse it for local UDP Sockets. If the API sees too many different UDP Ports from one IP within ~1 hour it will ban the IP. (So make sure you're reusing your UDP ports also for testing/debuging!)
The local port may be hardcoded, however, an option to manually specify another port should be offered.
Note when behind a NAT/masquerading router:
A session between the server and a client is identified by the ip and port used by the client. So when the port (or ip) changes within a session the client has to authenticate again. If a client is behind a nat router it can’t actually control the local port used for the connection. The router will normally translate the port to support several computers on a lan to share the internet connection. The public port (as determined by the router and seen by the server) which has been assigned to the connection will only be reserved for as long as it is in use. This means that the router will usually deallocate the port after a fixed timeout period (i.e. 5, 10 or 15 minutes). Once that happens the client will no longer be able to receive UDP messages from the server (the messages will be discarded as undeliverable by the router) and a new port will be selected once the client tries to send a message to the server (which will result in a new connection session - NOTE: this could get you banned!, see above). So in order to keep a session over a NAT router alive, the client has to ping the server within this period to prevent a timeout.
The client can decide whether it is behind a NAT router or not by adding nat=1 to the AUTH command. This will cause the response to include the ip and port as seen by the server. If the port differs from the port reported by the local socket, the connection subject to NAT and the client should issue PING commands in regular intervals. Please do not send pings more often then once every 5 minutes and only on connections via NAT routers or if the user has explicitly enabled regular keepalive pings via a configuration setting (default setting should be OFF).
Flood Protection
To prevent high server load the UDP API server enforces a strict flood protection policy.
- Short Term:
- A Client MUST NOT send more than 0.5 packets per second.
- The server will start to enforce the limit after the first 5 packets have been recieved.
- Long Term:
- A Client MUST NOT send more than one packet every 30 seconds over an extended amount of time.
- An extended amount of time is not defined. Use common sense.
Once a client exceeds a rate limit all further UDP packets from that client will be dropped without feedback until the client's packet rate is back down to acceptable levels.
NOTE: | Dropped packets are still taken into account for the packet rate. Meaning if you continuously send packets your client will be banned forever. |
Generally clients should be written in a way to minimize server and network load. You should always keep that in Mind. Abusive clients may be banned completly.
NOTE: | If you suddenly stop getting replies from the AniDB API or you normally don't have a noteable packetloss and from one point on you suddenly note a high packetloss percentage you have most likely entered a critical flood ratio.
If the AniDB API isn't answering at all it might either be down or you have been banned, this is normally caused by vialoating the API specs (i.e. too many connections using different ports from one ip, too many auth failures, ...) (usually lasts 30 minutes). If you're experiencing packet loss you have probably reached the rate limit and the API starts to randomly drop incoming packets from your IP. (can be solved by enforcing a delay between multiple commands when you're sending a batch) |
Anti Leech Protection
The API should not be used to "download" AniDB. If such attempts are detected you will get banned.
Caching
To minimize server and network load a client should use local caching in order to prevent repeated API requests for the same data.
A client should locally cache FILE/EP/ANIME/GROUP/... info wherever possible for extended amounts of time. (I.e. if a client is used to scan a local folder with anime files and add them via API to a users mylist then it shall only ask for all files in the first run and cache the info for all files known to AniDB. If run again over the same folder it shall only check those files which were unknown to anidb at the time of the last check.)
Later versions of the API might enforce this by banning clients which ask for the same information more than once every week/month.
Tag option
The api will add a user defined string at the beginning of each reply line seperated with a space, if desired.
- To enable add the tag={str usertag} option to a command.
- A tag is only valid for the command it was send with, meaning it is not persistent. If you want to have tags in front of all reply lines you will have to append the tag option to each command you send to the server.
- Tags are ment to enable a client to handle more than one request/reply at a time.
Usage example:
AUTH user=baka&pass=baka&protover=25&client=someclient&clientver=1&tag=abc123 abc123 200 Jxqxb LOGIN ACCEPTED
or
LOGOUT s=Jxqxb&tag=byebye byebye 203 LOGGED OUT
NOTE: | The tag option is valid for all api commands and is thus not explicitly listed in the description of each command. |
Data Indexes (fid,aid,eid,gid,lid)
- All indexes start at 1 (not 0).
- It is possible for table entries to have id fields with a value of 0 (i.e. gid). Those are to be interpreted as "NONE" or "NULL".
- An ID is never reused. That means after an entry is deleted no new entry will ever have that ID again.
Authing Commands
NOTE: | _ANY_ command which requires parameters may return: 505 ILLEGAL INPUT OR ACCESS DENIED |
AUTH: Authing to the AnimeDB
Command String:
- AUTH user={str username}&pass={str password}&protover={int4 apiversion}&client={str clientname}&clientver={int4 clientversion}[&nat=1&comp=1&enc={str encoding}&mtu{int4 mtu value}]
Possible Replies:
- 200 {str session_key} LOGIN ACCEPTED
- 201 {str session_key} LOGIN ACCEPTED - NEW VERSION AVAILABLE
- 500 LOGIN FAILED
- 503 CLIENT VERSION OUTDATED
- 504 CLIENT BANNED - {str reason}
- 505 ILLEGAL INPUT OR ACCESS DENIED
- 601 ANIDB OUT OF SERVICE - TRY AGAIN LATER
when nat=1
- 200 {str session_key} {str ip}:{int2 port} LOGIN ACCEPTED
- 201 {str session_key} {str ip}:{int2 port} LOGIN ACCEPTED - NEW VERSION AVAILABLE
Info:
- The session_key is a String containing only a-z,A-Z,0-9 chars of a length of 4-8 characters.
- It has to be stored by the client and needs to be sent as parameter with every command which requires the user to logged in.
- The session_key String is appended as parameter "s", i.e. "PUSH notify=1&msg=1&s={str session_key}".
- On a 500 LOGIN FAILED message the client should request the user to enter username and password again.
- In case of a 501 LOGIN FIRST message the client should silently resend an auth command and send the failed command again.
- A 502 ACCESS DENIED message should abort the current action on the client side and display a message to the user.
- A 503 CLIENT VERSION OUTDATED message states that the udp server has been updated and does not support your client any longer. (protover is too low). A 201 message referes to a new version of the client software.
- A 506 INVALID SESSION means that either the session key parameter "s" was not provided with a command that requires it or the session key is no longer valid. The client should reissue an AUTH command.
NOTE: | A frontend shall expect 501 and 502 messages to be returned on ANY command. |
NOTE: | Anidb usernames are always lowercase and may only contain characters (a-z) and numbers (0-9). |
- The client should silently convert all entered usernames to lowercase before sending them to the API.
- The client should send the apiversion of the AnimeDB API version it supports as value of the protover parameter.
- The client MAY NOT send anything but the version of the API Specs the author used to write the client! (as it is stated at the top of this file @ "Version number used for protover parameter")
- The API will compare that value to it's own version of the API and if the version of the client is older the API will decide wheter the changes were significant enough to deny the old client access to the DB.
- The clientname shall be a lowercase string containing only the chars a-z of 4-16 chars length which identifies the client. (i.e. mykickassclient)
- The clientversion shall be a number starting with 1, increased on every change in the client.
- clientname and clientversion might be used by the API to distinguish between different clients and client versions if that should ever become nessecary.
IMPORTANT: |
|
- A Login and its assigned session_key is valid until the virtual UDP connection times out or until a LOGOUT command is issued.
- The virtual UDP connection times out if no data was recieved from the client for 35 minutes.
- A client should issue a NOTIFY command once every 30 minutes to keep the connection alive should that be required.
- If the client does not use any of the notification/push features of the API it should NOT keep the connection alive, furthermore it should explicitly terminate the connection by issueing a LOGOUT command once it finished it's work.
- If it is very likely that another command will be issued shortly (within the next 20 minutes) a client may keep the current connection open, until it times out on it's own, by not sending a LOGOUT command.
- The client shall notify the user if it recieved a 201 message at login.
- This means a new version of the client is available, however the old version is still supported otherwise a client banned message would have been returned.
- The user should get a popup message on 503 and 504 messages telling him to update his client software.
- (NOTE: 504 means that this version of the client is banned, not the user!)
- The 'nat' option makes the client able to detect whether it is behind a nat router or not. When the client is behind a nat router it should keep the "connection" alive with the PING command.
IMPORTANT: | Make sure your client handels ALL possible AUTH return codes before giving out any versions! |
- When enc=x is defined the server will change the encoding used to x.
- If the encoding is supported it will change right away (including the response) and be reset on logout/timeout.
- If not supported then the argument will be silently ignored. Use ENCODING to test what works.
- Supported encodings are these.
- comp=1 means that the client supports compression (DEFLATE).
- The server will compress (instead of truncating) the datagrams when needed if this option is enabled.
- The first two bytes of compressed datagrams will always be set to zero. (So tags should never start with that.)
- Default mtu is 1400. Min = 400, Max = 1400.
LOGOUT: Logout
Command String:
- LOGOUT
Possible Replies:
- 203 LOGGED OUT
- 403 NOT LOGGED IN
Info:
- This command only works if you are already logged in.
- A logout should ALWAYS be issued if the client is currently logged in and is either exiting or not expecting to send/receive any anidb api packets for the next >= 30 minutes.
Notify Commands
These commands offer a way to receive different types of notifications.
Simple HOWTO:
- PUSH to register.
- Listen for 271/272 NOTIFICATIONs (not 290).
- PUSHACK the NOTIFICATIONs received (with the supplied ids [nid]).
- Use NOTIFY to get number of notifications / NOTIFYLIST to get a list of the notifications (with ids [not nid]).
- Use NOTIFYGET to receive a notification.
- Use NOTIFYACK to remove a notification (from NOTIFYLIST).
It is probably a good idea to use tags to separate NOTIFICATIONs from the other communication. NOTIFICATIONs will never have tags.
PUSH: UDP Notification Registration
Command String:
- PUSH notify={bool push_file_added_notifications}&msg={bool push_msg_added_notifications}[&buddy={bool push_buddy_event_notifications}]
Possible Replies:
- 270 NOTIFICATION ENABLED
OR (if both values are 0)
- 370 NOTIFICATION DISABLED
Note:
- This command only works if you are logged in.
- With this command you can register your client as an observer for anidb notification and message events for the current user. If you are registered for one or both events the anidb server will send an UDP packet (format see below) on each change which affects the current user. The UDP packet is sent to the ip and port from which the AUTH command was recieved.
- UDP packets are resend 3 times, if the client does not acknowlege them. After that the client is logged out and no further notifies will be sent.
- On recieving any of the above packets the client has to issue a PUSHACK command with the notify_packet_id provided in the notification packet.
Notification Packet Format
File Added Notify:
271 {int4 notify_packet_id} NOTIFICATION {int4 aid}|{int4 date}|{int4 count}|{str animetitle}
- aid is the id of the affected anime
- date is the time of the event (in seconds since 1.1.1970)
- count is the number of events pending for this anime
- animetitle is the name of the affected anime
Message Added Notify:
272 {int4 notify_packet_id} NOTIFICATION {int2 type}|{int4 date}|{int4 senderuid}|{str sendername}|{str subject}
- type is the type of the message (0=normal msg, 1=annonymous, 2=system msg, 3=mod msg)
- date is the time the message was sent (in seconds since 1.1.1970)
- senderuid/sendername are the user id and username of the sender
- subject is the message subject
Buddy Event Notify:
273 {int4 notify_packet_id} NOTIFICATION {int4 buddy uid}|{int2 event type}
- Possible event types:
- 0 => LOGIN
- 1 => LOGOUT
- 2 => ACCEPTED
- 3 => ADDED
Going Down Event Notify:
274 {int4 notify_packet_id} NOTIFICATION {int4 time offline}|{int4 comment}
- Clients with any notification on will receive the GOINGDOWN message before the API goes offline.
- Time offline is the time in minutes the API will be down, 0 if indefinite (client can direct user to the anidb site for status updates).
- The comment is a short explanation for the downtime.
- Only one datagram will be sent, and the server will not listen for replies.
PUSHACK: UDP Notification Acknowledge
Command String:
- PUSHACK nid={int4 notify_packet_id}
Possible Replies:
- 280 PUSHACK CONFIRMED
- 380 NO SUCH PACKET PENDING
Info:
- This command only works if you are logged in.
- see: PUSH
NOTIFY: Notifications
Command String:
- NOTIFY [buddy=1]
Possible Replies:
- 290 NOTIFICATION
- {int4 pending_notifies}|{int4 pending_msgs}
when buddy=1
- 290 NOTIFICATION
- {int4 pending_notifies}|{int4 pending_msgs}|{int4 number_of_online_buddys}
Info:
- This command only works if you are logged in.
- pending_notifies is the number of animes which have pending notifications for this user.
- pending_msgs is the number of unread anidb messages for this user.
- A client which has registered to recieve UDP notification packets should issue this command once every 30 minutes to keep the connection alive and to ensure that it has not been logged out by the API server yet.
- If the client did send a NOTIFY within the last 35 minutes and it was confirmed by AniDB then recieving a 501 LOGIN FIRST message for the next NOTIFY command shows that AniDB logged the client out because it did not respond to a PUSH Notification packet.
- There is no command to retrieve missed PUSH Notifications.
NOTE: | This command MUST NOT be issued more than once every 20 minutes. |
NOTIFYLIST: List Notification/Message IDs
Command String:
- NOTIFYLIST
Possible Replies:
- 291 NOTIFYLIST
- {str type}|{int4 id}
- {str type}|{int4 id}
- ...
Info:
- This command only works if you are logged in.
- type is:
- M for message entries
- N for notification entries
- id is the identifier for the notification/message as required by NOTIFYGET.
- NOTIFYLIST returns one line per entry, if no entries are available only the first line of the reply is returned.
NOTE: | This command MUST NOT be issued regulary but should only be triggered by either a push message recieved by the client or a reply to a NOTIFY command which tells you that there are messages/notifications waiting. |
NOTIFYGET: Get Notification/Message
Command String:
- NOTIFYGET type={str type}&id={int4 id}
Possible Replies:
when type = M
- 292 NOTIFYGET
- {int4 id}|{int4 from_user_id}|{str from_user_name}|{int4 date}|{int4 type}|{str title}|{str body}
- 392 NO SUCH ENTRY
when type = N
- 293 NOTIFYGET
- {int4 aid}|{int4 type}|{int2 count}|{int4 date}|{str anime_name}
- 393 NO SUCH ENTRY
Info:
- This command only works if you are logged in.
- type is:
- M for message entries
- N for notification entries
- id is the identifier for the notification/message as required by NOTIFYGET.
- for message entries (M):
- date is the time of the event (in seconds since 1.1.1970)
- type is the type of the message (0=normal msg, 1=annonymous, 2=system msg, 3=mod msg)
- for notification entries (N):
- aid is the id of the affected anime
- type is the notification type (0=all, 1=new, 2=group)
- count is the number of events pending for this anime
- date is the time of the event (in seconds since 1.1.1970)
NOTIFYACK: Acknowledge Notification/Message
Command String:
- NOTIFYACK type={str type}&id={int4 id}
Possible Replies:
when type = M
- 281 NOTIFYACK SUCCESSFUL
- 381 NO SUCH ENTRY
when type = N
- 282 NOTIFYACK SUCCESSFUL
- 382 NO SUCH ENTRY
Info:
- This command only works if you are logged in.
- This command will mark a message read or clear a notification.
- type is:
- M for message entries
- N for notification entries
Buddy Commands
Group of commands used to administrate your buddylist.
BUDDYADD: Add a user to Buddy List
Command String:
- BUDDYADD uid={int4 buddy uid}
- BUDDYADD uname={int4 buddy name}
Possible Replies:
- 394 NO SUCH USER
- 255 BUDDY ADDED
- 355 BUDDY ALREADY ADDED
BUDDYDEL: Remove a user from Buddy List
Command String:
- BUDDYDEL uid={int4 buddy uid}
Possible Replies:
- 356 NO SUCH BUDDY
- 256 BUDDY DELETED
BUDDYACCEPT: Accept user as Buddy
Command String:
- BUDDYACCEPT uid={int4 user uid}
Possible Replies:
- 356 NO SUCH BUDDY
- 257 BUDDY ACCEPTED
- 357 BUDDY ALREADY ACCEPTED
BUDDYDENY: Deny user as Buddy
Command String:
- BUDDYDENY uid={int4 buddy uid}
Possible Replies:
- 394 NO SUCH USER
- 258 BUDDY DENIED
- 358 BUDDY ALREADY DENIED
BUDDYLIST: Retrieve Buddy List
Command String:
- BUDDYLIST startat={int2 start at #}
Possible Replies:
- 253 {int2 start} {int2 end} {int2 total} BUDDY LIST
- {int4 uid}|{str username}|{int2 state}
- ...
Info:
- state is a 16bit bit field in integer notation (lowest bit first):
* bit 1 = this user is in your buddylist * bit 2 = this user has accepted you * bit 3 = this user is waiting for your approval
BUDDYSTATE: Retrieve Buddy States
Command String:
- BUDDYSTATE startat={int2 start at #}
Possible Replies:
- 254 {int2 start} {int2 end} {int2 total} BUDDY STATE
- {int4 uid}|{int2 onlinestate}
- ...
Info:
- onlinestate is a 16bit bit field in integer notation (lowest bit first):
* bit 1 = http online (user has issued a HTTP request within the last 10 minutes) * bit 2 = udp api online (user is currently connected to the udp api server) * example: 0=offline, 1=http online, 2=udp api online, 3=http&udp api online
Data Commands
ANIME: Retrieve Anime Data
Command String:
by aid
- ANIME aid={int4 id}[&acode={int4}]
by name
- ANIME aname={str anime name}[&acode={int4}]
Possible Replies:
- 230 ANIME
- {int4 aid}|{int4 eps}|{int4 ep count}|{int4 special cnt}|{int4 rating}|{int4 votes}|{int4 tmprating}|{int4 tmpvotes}|{int4 review rating average}|{int4 reviews}|{str year}|{str type}|{str romaji}|{str kanji}|{str english}|{str other}|{str short names}|{str synonyms}|{str category list}
- 330 NO SUCH ANIME
Info:
- Synonyms and short names are separated with '
- Category names are separated with ',' and ordered by weight (desc).
- No support for genres.
- By name: must be perfect match of romaji/kanji/english/other/synonym/short name.
- NOTE: The category list is the first data to be truncated if needed. And then: synonym list, short name list. This applies for the FILE command too.
acode:
Bit | Decimal | Data field | - | Bit | Decimal | Data field |
---|---|---|---|---|---|---|
0 | 1 | int4 aid | 16 | 65536 | str url | |
1 | 2 | int4 episodes | 17 | 131072 | str picname | |
2 | 4 | int4 normal ep count | 18 | 262144 | str year | |
3 | 8 | int4 special ep count | 19 | 524288 | str type | |
4 | 16 | int4 rating | 20 | 1048576 | str romaji name | |
5 | 32 | int4 vote count | 21 | 2097152 | str kanji name | |
6 | 64 | int4 temp rating | 22 | 4194304 | str english name | |
7 | 128 | int4 temp vote count | 23 | 8388608 | str other name | |
8 | 256 | int4 average review rating | 24 | 16777216 | str short name list | |
9 | 512 | int4 review count | 25 | 33554432 | str synonym list | |
10 | 1024 | int4 air date | 26 | 67108864 | str category list | |
11 | 2048 | int4 end date | 27 | 134217728 | str related aid list | |
12 | 4096 | int4 anime planet id | 28 | 268435456 | str producer name list | |
13 | 8192 | int4 anime news network id | 29 | 536870912 | str producer id list | |
14 | 16384 | int4 allcinema id | 30 | 1073741824 | str award list | |
15 | 32768 | str animenfo id | 31 | -2147483648 | reserved (all) |
Examples: (html escaped code intended)
> ANIME aname=tmm&s=xxxxx < 230 ANIME 161|52|50|0|715|57|777|35|816|1|2002-2003|TV|Tokyo Mew Mew|東京ミュウミュウ||||TMM'mew|Cat Girls
> ANIME aname=ナルト&s=xxxxx < 230 ANIME 239|0|140|2|1000|10|855|3750|803|36|2002-2005|TV|Naruto|ナルト||נארוטו|NARUTO'ناروتو|naruto tv'ntv|Action,Shounen,Past,...(cut)
EPISODE: Retrieve Episode Data
Command String:
by eid
- EPISODE eid={int4 eid}
by anime and episode number
- EPISODE aname={str anime name}&epno={int4 episode number}
- EPISODE aid={int4 anime id}&epno={int4 episode number}
Possible Replies:
- 240 EPISODE
- {int4 eid}|{int4 aid}|{int4 length}|{int4 rating}|{int4 votes}|{str epno}|{str eng}|{str romaji}|{str kanji}
- 340 NO SUCH EPISODE
Info:
- length is in minutes
- Returned 'epno' includes special character (only if special) and padding (only if normal). Special characters are S(special), C(credits), T(trailer), P(parody), O(other).
Examples: (html escaped code intended)
> EPISODE eid=1&s=xxxxx < 240 EPISODE 1|1|24|400|4|01|Invasion|shinryaku|??
> EPISODE aname=Seikai no Monshou&epno=2&s=xxxxx < 240 EPISODE 2|1|24|750|2|02|Kin of the Stars|Hoshi-tachi no Kenzoku|??????
FILE: Retrieve File Data
Command String:
by fid:
- FILE fid={int4 id}[&fcode={int4}&acode={int4}]
by size+ed2k hash:
- FILE size={int4 size}&ed2k={str ed2khash}[&fcode={int4}&acode={int4}]
by anime, group and epno
- FILE aname={str anime name}&gname={str group name}&epno={int4 episode number}[&fcode={int4}&acode={int4}]
- FILE aname={str anime name}&gid={int4 group id}&epno={int4 episode number}[&fcode={int4}&acode={int4}]
- FILE aid={int4 anime id}&gname={str group name}&epno={int4 episode number}[&fcode={int4}&acode={int4}]
- FILE aid={int4 anime id}&gid={int4 group id}&epno={int4 episode number}[&fcode={int4}&acode={int4}]
Possible Replies:
- 220 FILE
- {int4 fid}|{int4 aid}|{int4 eid}|{int4 gid}|{int4 state}|{int4 size}|{str ed2k}|{str anidbfilename}
- 220 FILE
- {int4 fid}|...(data list)
- 322 MULTIPLE FILES FOUND
- {int4 fid 0}|{int4 fid 1}|...|{int4 fid n}
- 320 NO SUCH FILE
Info:
- fid, aid, eid, gid are the unique ids for the file, anime, ep, group entries at anidb.
- You can use those to create links to the corresponding pages at anidb.
- anidbfilename is the anidb filename for the file.
- However this name does not contain all the extra information of the filenames on AniDB and might be composed slightly different.
- fcode and acode is integers where each bit corresponds to a data field related to the specified file (se below). The data list received is sorted in the same order as the tables (and fcode before acode). {f|a}code=-1 means retrieve all fields.
- Only the first matching file is returned when aname, gname and epno is used.
State:
bit / int value meaning 1 / 1 FILE_CRCOK: file matched official crc (displayed with green background in anidb) 2 / 2 FILE_CRCERR: file DID NOT match official crc (displayed with red background in anidb) 3 / 4 FILE_ISV2: file is version 2 4 / 8 FILE_ISV3: file is version 3 5 / 16 FILE_ISV4: file is version 4 6 / 32 FILE_ISV5: file is version 5 7 / 64 FILE_UNC: file is uncensored 8 / 128 FILE_CEN: file is censored examples: state ==== 9 ==> FILE_CRCOK+FILE_ISV3 ==> file matched official crc and is version 3 state ==== 0 ==> - ==> file was not crc checked and is version 1 state ==== 34 ==> FILE_CRCERR+FILE_ISV5 ==> file DID NOT match official crc and is version 5 state ==== 1 ==> FILE_CRCOK ==> file matched official crc and is version 1 state ==== 8 ==> FILE_ISV3 ==> file was not crc checked and is version 3
fcode:
Bit | Decimal | Data field | - | Bit | Decimal | Data field |
---|---|---|---|---|---|---|
0 | 1 | not used | 16 | 65536 | str dub language | |
1 | 2 | int4 aid | 17 | 131072 | str sub language | |
2 | 4 | int4 eid | 18 | 262144 | str quality | |
3 | 8 | int4 gid | 19 | 524288 | str source | |
4 | 16 | int4 lid | 20 | 1048576 | str audio codec | |
5 | 32 | not used | 21 | 2097152 | int4 audio bitrate | |
6 | 64 | not used | 22 | 4194304 | str video codec | |
7 | 128 | not used | 23 | 8388608 | int4 video bitrate | |
8 | 256 | int2 state | 24 | 16777216 | str video resolution | |
9 | 512 | int4 size | 25 | 33554432 | str file type (extension) | |
10 | 1024 | str ed2k | 26 | 67108864 | int4 length in seconds | |
11 | 2048 | str md5 | 27 | 134217728 | str description | |
12 | 4096 | str sha1 | 28 | 268435456 | not used | |
13 | 8192 | str crc32 | 29 | 536870912 | not used | |
14 | 16384 | not used | 30 | 1073741824 | str anidb file name | |
15 | 32768 | not used | 31 | -2147483648 | not used |
acode:
Bit | Decimal | Data field | - | Bit | Decimal | Data field |
---|---|---|---|---|---|---|
0 | 1 | str group name | 16 | 65536 | int4 anime total episodes | |
1 | 2 | str group short name | 17 | 131072 | int4 last episode nr (highest, not special) | |
2 | 4 | not used | 18 | 262144 | str year | |
3 | 8 | not used | 19 | 524288 | str type | |
4 | 16 | not used | 20 | 1048576 | str romaji name | |
5 | 32 | not used | 21 | 2097152 | str kanji name | |
6 | 64 | not used | 22 | 4194304 | str english name | |
7 | 128 | not used | 23 | 8388608 | str other name | |
8 | 256 | str epno | 24 | 16777216 | str short name list | |
9 | 512 | str ep name | 25 | 33554432 | str synonym list | |
10 | 1024 | str ep romaji name | 26 | 67108864 | str category list | |
11 | 2048 | str ep kanji name | 27 | 134217728 | str related aid list | |
12 | 4096 | not used | 28 | 268435456 | str producer name list | |
13 | 8192 | not used | 29 | 536870912 | str producer id list | |
14 | 16384 | not used | 30 | 1073741824 | not used | |
15 | 32768 | not used | 31 | -2147483648 | not used |
Examples: (html escaped code intended)
> FILE fid=15201&s=xxxxx < 220 FILE 15201|74|445|41|1|242772540|a53c401ed95eaa502ba85acde773040c|Ai yori Aoshi - 1 - Relation - [Zhentarim DivX].ogm > FILE fid=15201&fcode=33554432&acode=1049346 < 220 FILE 15201|ogm|zx|01|Relation|Ai yori Aoshi > FILE aname=narutaru&gname=triad&aone&epno=2&s=xxxxx < t001 220 FILE 15459|782|8772|380|1|171298816|2c8a3b53d94d8579b9b81941c549e108|Narutaru - 02 - Catastrophe During the Daytime - [Triad & AonE].avi
GROUP: Retrieve Group Data
Command String:
by gid
- GROUP gid={int4 gid}
by name/shortname
- GROUP gname={str group name}
Possible Replies:
- 250 GROUP
- {int4 gid}|{int4 rating}|{int4 votes}|{int4 acount}|{int fcount}|{str name}|{str short}|{str irc channel}|{str irc server}|{str url}
- 350 NO SUCH GROUP
Examples:
> GROUP gid=1&s=xxxxx < 250 GROUP 41|851|665|109|1004|Zhentarim DivX|zx|#zhentarim|irc.deltaanime.net|http://www.zhentarim.net/
> GROUP gname=a-l&s=xxxxx < 250 GROUP 566|840|453|53|534|Anime-Legion|A-L|#anime-legion|irc.irchighway.net|http://www.anime-legion.net
PRODUCER: Retrieve Producer Data
Command String:
by id
- PRODUCER pid={int4 producer id}
by name
- PRODUCER pname={str producer name/short name/other name}
Possible Replies:
- 245 PRODUCER
- {int4 id}|{str name}|{str short name}|{str other name}|{str type}|{str picture name}|{str home page url}
- 345 NO SUCH PRODUCER
Example:
> PRODUCER pid=1 < 245 PRODUCER 1|GAINAX||ガイナックス|Company|1088.gif|http://www.gainax.co.jp/
Mylist Commands
MYLIST: Retrieve Mylist Data
Command String:
by lid: (mylist id)
- MYLIST lid={int4 lid}
by fid:
- MYLIST fid={int4 fid}
by size+ed2k hash:
- MYLIST size={int4 size}&ed2k={str ed2khash}
by anime + group + epno
- MYLIST aname={str anime name}[&gname={str group name}&epno={int4 episode number}]
- MYLIST aname={str anime name}[&gid={int4 group id}&epno={int4 episode number}]
- MYLIST aid={int4 anime id}[&gname={str group name}&epno={int4 episode number}]
- MYLIST aid={int4 anime id}[&gid={int4 group id}&epno={int4 episode number}]
Possible Replies:
- 221 MYLIST
- {int4 lid}|{int4 fid}|{int4 eid}|{int4 aid}|{int4 gid}|{int4 date}|{int2 state}|{int4 viewdate}|{str storage}|{str source}|{str other}
- 312 MULTIPLE MYLIST ENTRIES
- {str anime title}|{int episodes}|{str eps with state unknown}|{str eps with state on hhd}|{str eps with state on cd}|{str eps with state deleted}|{str watched eps}|{str group 1 short name}|{str eps for group 1}|...|{str group N short name}|{str eps for group N}
- 321 NO SUCH ENTRY
Info:
- The state field provides information about the location and sharing state of a file in mylist.
- If files are added after hashing, a client should specify the state as 1 (on hdd) (if the user doesn't explicitly select something else).
- eps is a list of episodes, e.g. "1-12,14-16,T1"
States:
0 - unknown - state is unknown or the user doesn't want to provide this information 1 - on hdd - the file is stored on hdd (but is not shared) 2 - on cd - the file is stored on cd 3 - deleted - the file has been deleted or is not available for other reasons (i.e. reencoded)
Example:
> MYLIST aname=gits sac&s=xxxxx < 322 MULTIPLE FILES FOUND Koukaku Kidoutai STAND ALONE COMPLEX|26||1-26|1-26,S2-S27|||V-A|S2-S27|LMF|20-26|KAA|1-26|AonE|1-19|Anime-MX|1-3,9-20
MYLISTADD: Add file to mylist
Command String:
by lid: (mylist id, edit only)
- MYLISTADD lid={int4 lid}&edit=1[&state={int2 state}&viewed={boolean viewed}&source={str source}&storage={str storage}&other={str other}]
by fid:
- MYLISTADD fid={int4 fid}[&state={int2 state}&viewed={boolean viewed}&source={str source}&storage={str storage}&other={str other}][&edit=1]
by size+ed2k hash:
- MYLISTADD size={int4 size}&ed2k={str ed2khash}[&state={int2 state}&viewed={boolean viewed}&source={str source}&storage={str storage}&other={str other}][&edit=1]
by anime + group + epno
- MYLISTADD aname={str anime name}[&gname={str group name}&epno={int4 episode number}][&state={int2 state}&viewed={boolean viewed}&source={str source}&storage={str storage}&other={str other}][&edit=1]
- MYLISTADD aname={str anime name}[&gid={int4 group id}&epno={int4 episode number}][...]
- MYLISTADD aid={int4 anime id}[&gname={str group name}&epno={int4 episode number}][...]
- MYLISTADD aid={int4 anime id}[&gid={int4 group id}&epno={int4 episode number}][...]
Possible Replies:
- 320 NO SUCH FILE
- 330 NO SUCH ANIME
- 350 NO SUCH GROUP
when edit=0
- 210 MYLIST ENTRY ADDED
- {int4 number of entries added}
- 310 FILE ALREADY IN MYLIST
- 322 MULTIPLE FILES FOUND
- {int4 fid 1}|{int4 fid 2}|...|{int4 fid n}
when edit=1
- 311 MYLIST ENTRY EDITED
- 311 MYLIST ENTRY EDITED
- {int4 number of entries edited}
- 411 NO SUCH MYLIST ENTRY
Info:
- All data except lid/fid/size+hash is optional.
- Viewed should be 0 for unwatched files and 1 for watched files.
- Other is the only field which may contrain newlines, but they have to be stored as <br />
- If edit is 1 then an existing entry, if found, will be updated with the given values.
- For state values refer to: MYLIST
- If you want to change an existing entry and already know it's mylist id (lid) please use the lid-version of this command. It put less load on the server.
- epno=0 means all eps (default), negative numbers means upto. (-12 -> upto 12)
- group is optional only when edit=1, meaning you can't add every file for an anime
NOTE: | Currently this command does not update the internal caches of AniDB. Using this command will lead to wrong stats values/counts being displayed in your Mylist & co @ AniDB according to the Routine Maintenance. |
NOTE: | Currently this command will replace all mylist fields this commands supports, even if they were not specified by the client. I.e. an update with "MYLISTADD lid={int4 lid}&edit=1&viewed=1" will reset the state,source,storage and other fields to their default values. |
NOTE: | Currently this command will reset the date of the file watched despite the state of the entry was already maked as "viewed". |
MYLISTDEL: Remove file from mylist
Command String:
by lid: (mylist id)
- MYLISTDEL lid={int4 lid}
by fid:
- MYLISTDEL fid={int4 fid}
by anime + group + epno
- MYLISTDEL aname={str anime name}[&gname={str group name}&epno={int4 episode number}]
- MYLISTDEL aname={str anime name}[&gid={int4 group id}&epno={int4 episode number}]
- MYLISTDEL aid={int4 anime id}[&gname={str group name}&epno={int4 episode number}]
- MYLISTDEL aid={int4 anime id}[&gid={int4 group id}&epno={int4 episode number}]
Possible Replies:
- 211 MYLIST ENTRY DELETED
- {int4 number of entries}
- 411 NO SUCH MYLIST ENTRY
Info:
- group is optional
- command will delete all enties found
MYLISTSTATS : Retrieve mylist stats
Command String:
- MYLISTSTATS
Possible Replies:
- 222 MYLIST STATS
{animes}|{eps}|{files}|{size of files}|{added animes}|{added eps}|{added files}|{added groups}|{leech %}|{lame %}|{viewed % of db}|{mylist % of db}|{viewed % of mylist}|{number of viewed eps}|{votes}|{reviews}
Info:
- All fields are int
VOTE: Vote for specified anime/episode/group
Command String:
by id
- VOTE type={int2 type}&id={int4 id}[&value={int4 vote value}&epno={int4 episode number}]
by name
- VOTE type={int2 type}&name={string name}[&value={int4 vote value}&epno={int4 episode number}]
Possible Replies:
- 260 VOTED
- {str aname/ename/gname}
- 261 VOTE FOUND
- {str aname/ename/gname}|{vote value}
- 262 VOTE UPDATED
- {str aname/ename/gname}|{old vote value}
- 263 VOTE REVOKED
- {str aname/ename/gname}|{revoked vote value}
- 360 NO SUCH VOTE
- 361 INVALID VOTE TYPE
- 362 INVALID VOTE VALUE
- 363 PERMVOTE NOT ALLOWED
- {str aname}
- 364 ALREADY PERMVOTED
- {str aname/ename/gname}
Info:
- type: 1=anime, 2=anime tmpvote, 3=group
- for episode voting add epno on type=1
- value: negative number means revoke, 0 means retrieve (default), 100-1000 are valid vote values, rest is illegal
- votes will be updated automatically (no questions asked)
- tmpvoting when there exist a perm vote is not possible
RANDOM: Get a random anime
Command String:
- RANDOMANIME type={int4 type}
Possible Replies:
- 230 ANIME ... (see ANIME)
Info:
- type: 0=from db, 1=watched, 2=unwatched, 3=all mylist
Misc Commands
PING: Ping Command
Command String:
- PING [nat=1]
Possible Replies:
- 300 PONG
- {int4 port} (when nat=1)
Info:
- May be used by a frontend to determine if the API is still available.
- May be executed even if not yet logged in.
- The option nat=1 provides an easy way to determine if the router has changed the outgoing port. (587)
ENCRYPT: Start Encrypted Session
Will cause all future messages from the server, except the first (the reply to the ENCRYPT command itself), to be encrypted (128 bit AES). The client will also have to encrypt all future requests sent to the server. All non-encrypted messages will be discarded by the server. The encryption key is the MD5 hash of a special API Password (defined in the users profile) concatenated with the salt string as given in the reply to the ENCRYPT message. A normal AUTH message is still necessary to authenticate and should follow the ENCRYPT command once the API has acknowledged the encryption.
Command String:
- ENCRYPT user={str name}&type={int2 type}
Possible Replies:
- 209 {str salt} ENCRYPTION ENABLED
- 309 API PASSWORD NOT DEFINED
- 509 NO SUCH ENCRYPTION TYPE
- 394 NO SUCH USER
Info:
- user is the user name.
- type is the type of encryption; 1 => 128 bit AES (only one defined).
- API Password is the one defined in the profile settings page.
- It is not possible to disable the encryption once enabled while staying logged in.
- A logout (the logout message needs to be correctly encrypted) or timeout will disable the encryption.
- In order to minimize server load, encryption should be disabled by default and should have to be enabled manually by the user in the configuration options.
- The encryption key is md5(api_password_of_user+salt).
- Padding of the message needs to be done according to the PKCS5Padding scheme.
ENCODING: Change Encoding for Session
Sets preferred encoding per session.
Command String:
- ENCODING name={str encoding name}
Possible Replies:
- 219 ENCODING CHANGED
- 519 ENCODING NOT SUPPORTED
Info:
- Supported encodings: http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
- Default: ASCII.
- Resets to default on logout.
SENDMSG: Send Message
Command String:
- SENDMSG to={str username}&title={str title}&body={str body}
Possible Replies:
- 294 SENDMSG SUCCESSFUL
- 394 NO SUCH USER
- 501 LOGIN FIRST
Note:
- This command allows you to send an AniDB message.
IMPORTANT: | title must not be longer than 50 chars.
body must not be longer than 900 chars. |
USER: Retrieve User UID
Command String:
- USER user={str user name}
Possible Replies:
- 394 NO SUCH USER
- 295 USER
- {int4 uid}
Info:
- The client should the check length (3-10) and case (lower) of user before sending.
UPTIME: Retrieve Server Uptime
Command String:
- UPTIME
Possible Replies:
- 208 UPTIME
- {int4 udpserver uptime in milliseconds}
VERSION: Retrieve Server Version
Command String:
- VERSION
Possible Replies:
- 998 VERSION
- {str server version}
STATS [disabled]
Command String:
- STATS
Possible Replies:
- 206 STATS
- {int4 animes)|{int4 eps}|{int4 files}|{int4 groups}|{int4 users}|{int8 total file size in bytes}|{int4 open creqs}
TOP [disabled]
Command String:
- TOP
Possible Replies:
- 207 TOP
- {str longest mylist}|{int count}
- {str largest mylist}|{int count}
- {str most lame files}|{int count}
- {str most indep. user}|{int count}
- {str biggest leecher}|{int count}
- {str most anime added}|{int count}
- {str most eps added}|{int count}
- {str most files added}|{int count}
- {str most groups added}|{int count}
- {str most votes}|{int count}
- {str most reviews}|{int count}
Info:
- All strings are user names.
- 'Hide myself in IRC stats' applies for this too.
Fatal Errors
At anypoint int the retrieval process you have to expect the following output:
- 6xx INTERNAL SERVER ERROR
- ERROR: {str errormessage}
OR
- 6xx INTERNAL SERVER ERROR - {str errormessage}
Such errors should be reported back to Epoximator. (xx is a number between 00 and 99)
If you supply an unknown or unimplemented command you will get an error:
- 598 UNKNOWN COMMAND
Return Codes
Note: The names below do _not_ necessarily reflect the actual code strings returned by the server.
// POSITIVE 2XX LOGIN_ACCEPTED =200, //a LOGIN_ACCEPTED_NEW_VER =201, //a LOGGED_OUT =203, //a RESOURCE =205, //d STATS =206, //b TOP =207, //b UPTIME =208, //b ENCRYPTION_ENABLED =209, //c MYLIST_ENTRY_ADDED =210, //a MYLIST_ENTRY_DELETED =211, //a ADDED_FILE =214, //e ADDED_STREAM =215, //e ENCODING_CHANGED =219, //c FILE =220, //a MYLIST =221, //a MYLIST_STATS =222, //b ANIME =230, //b ANIME_BEST_MATCH =231, //b RANDOMANIME =232, //b EPISODE =240, //b PRODUCER =245, //b GROUP =250, //b BUDDY_LIST =253, //c BUDDY_STATE =254, //c BUDDY_ADDED =255, //c BUDDY_DELETED =256, //c BUDDY_ACCEPTED =257, //c BUDDY_DENIED =258, //c VOTED =260, //b VOTE_FOUND =261, //b VOTE_UPDATED =262, //b VOTE_REVOKED =263, //b NOTIFICATION_ENABLED =270, //a NOTIFICATION_NOTIFY =271, //a NOTIFICATION_MESSAGE =272, //a NOTIFICATION_BUDDY =273, //c NOTIFICATION_SHUTDOWN =274, //c PUSHACK_CONFIRMED =280, //a NOTIFYACK_SUCCESSFUL_M =281, //a NOTIFYACK_SUCCESSFUL_N =282, //a NOTIFICATION =290, //a NOTIFYLIST =291, //a NOTIFYGET_MESSAGE =292, //a NOTIFYGET_NOTIFY =293, //a SENDMSG_SUCCESSFUL =294, //a USER =295, //d // AFFIRMATIVE/NEGATIVE 3XX PONG =300, //a AUTHPONG =301, //c NO_SUCH_RESOURCE =305, //d API_PASSWORD_NOT_DEFINED =309, //c FILE_ALREADY_IN_MYLIST =310, //a MYLIST_ENTRY_EDITED =311, //a MULTIPLE_MYLIST_ENTRIES =312, //e SIZE_HASH_EXISTS =314, //c INVALID_DATA =315, //c STREAMNOID_USED =316, //c NO_SUCH_FILE =320, //a NO_SUCH_ENTRY =321, //a MULTIPLE_FILES_FOUND =322, //b NO_SUCH_ANIME =330, //b NO_SUCH_EPISODE =340, //b NO_SUCH_PRODUCER =345, //b NO_SUCH_GROUP =350, //b BUDDY_ALREADY_ADDED =355, //c NO_SUCH_BUDDY =356, //c BUDDY_ALREADY_ACCEPTED =357, //c BUDDY_ALREADY_DENIED =358, //c NO_SUCH_VOTE =360, //b INVALID_VOTE_TYPE =361, //b INVALID_VOTE_VALUE =362, //b PERMVOTE_NOT_ALLOWED =363, //b ALREADY_PERMVOTED =364, //b NOTIFICATION_DISABLED =370, //a NO_SUCH_PACKET_PENDING =380, //a NO_SUCH_ENTRY_M =381, //a NO_SUCH_ENTRY_N =382, //a NO_SUCH_MESSAGE =392, //a NO_SUCH_NOTIFY =393, //a NO_SUCH_USER =394, //a // NEGATIVE 4XX NOT_LOGGED_IN =403, //a NO_SUCH_MYLIST_FILE =410, //a NO_SUCH_MYLIST_ENTRY =411, //a // CLIENT SIDE FAILURE 5XX LOGIN_FAILED =500, //a LOGIN_FIRST =501, //a ACCESS_DENIED =502, //a CLIENT_VERSION_OUTDATED =503, //a CLIENT_BANNED =504, //a ILLEGAL_INPUT_OR_ACCESS_DENIED =505, //a INVALID_SESSION =506, //a NO_SUCH_ENCRYPTION_TYPE =509, //c ENCODING_NOT_SUPPORTED =519, //c BANNED =555, //a UNKNOWN_COMMAND =598, //a // SERVER SIDE FAILURE 6XX INTERNAL_SERVER_ERROR =600, //a ANIDB_OUT_OF_SERVICE =601, //a SERVER_BUSY =602, //d API_VIOLATION =666, //a
Changelog
0.03b - 23.07.2006 BUDDY*, PRODUCER, ENCRYPT, ENCODING, USER, VERSION commands added AUTH, NOTIFY, ANIME, FILE commands extended STATS and TOP commands disabled due performance issues several fixes 0.03 - 13.01.2006 ANIME, EPISODE, GROUP, STATS, TOP, UPTIME, MYLISTSTATS, VOTE and RANDOM commands added it is now possible to use html escaped code in mylist fields, and '=' updated epno in default file name (for new specials) ... (a lot of stuff already forgotten) 0.02c - 10.10.2004 LOGOUT now requires the session string too Note on 6xx server errors and tags added 0.02b - 14.08.2004 503 INVALID SESSION changed to 506 INVALID SESSION BUGFIX: 200 message on AUTH did not contain a session key BUGFIX: 1 internal bug fixed 0.02 - 13.08.2004 new session key needs to be send with each command random udp ports no longer required FILE, MYLIST, MYLISTDEL, MYLISTADD commands added Some textparts of return values changed additional documentation added check the caching section! 0.01b - 12.08.2004 added NOTIFYLIST, NOTIFYGET, NOTIFYACK, SENDMSG commands 0.01 - 10.08.2004 initial version