UDP API Definition: Difference between revisions

m
Fix typo in return code 282 name (NOTIFYACK_SUCCESSFUL_NOTIFICATION -- was [...]_NOTIFIATION)
m (Fix typo in return code 282 name (NOTIFYACK_SUCCESSFUL_NOTIFICATION -- was [...]_NOTIFIATION))
 
(183 intermediate revisions by 15 users not shown)
Line 1: Line 1:
{{TOCright}}
{{TOCright}}
== General Information ==
== General Information ==
'''Author:''' [[User:Exp|Exp]] & [[User:Epoximator|Epoximator]]<br>
'''Author:''' [[User:Exp|Exp]] & [[User:Epoximator|Epoximator]] & [[User:Ommina|Ommina]]<br>
'''Version:''' 0.03.035 (2007-05-06)<br>
'''Version:''' 0.03.730 (2015-03-25)<br>
'''Version number used for protover parameter:''' "3"
'''Version number used for protover parameter:''' "3"


'''IMPORTANT INFORMATION FOR ALL INTERESTED:'''
'''IMPORTANT INFORMATION FOR ALL INTERESTED:'''
* If you are mainly interested in notifications and private messaging, check out our [[Jabber]] support first.
* If you are mainly interested in notifications and private messaging, check out our [[Jabber]] and [[RSSRDF]] support first.
* If you are mainly interested in downloading a local copy of anidb, use the [[TCP API]] or go away.
* The UDP API is not an appropriate choice if you desire to download a local copy of the AniDB database.
* If you want to create a client you have to register it [http://anidb.info/perl-bin/animedb.pl?show=client here] and [[UDP_Clients|here]].
* If you want to create a client you have to register it {{AniDBLink|client|here}} and [[UDP Clients|here]].
** Check out the clients that are being developed. There exists usable code in many different languages already.
** 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 [[UDP_API_DEV|development]] page.
* If you have suggestions for improvements or new features use the [[UDP API DEV|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 <tt>anidb.udp.api-request@freelists.org</tt> with ''subscribe'' as the subject.
* Please also take a look at the [[API]] page.


== Formats used in this Spec ==
== Formats used in this Spec ==
Line 20: Line 21:
* ''int2'' - 2 byte Integer (in string representation)
* ''int2'' - 2 byte Integer (in string representation)
* ''int4'' - 4 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)
* ''boolean'' - true or false - use '1' for ''true'', '0' for ''false''
* ''str'' - String (UDP packet length restricts string size to 1400 bytes)
* ''hexstr'' -- a hex representation of a decimal value, two characters per byte.  If multiple bytes are represented, byte one is the first two characters of the string, byte two the next two, and so on.


=== Content Encoding ===
=== Content Encoding ===
Line 28: Line 31:
** All newlines should be replaced by &lt;br /&gt;
** All newlines should be replaced by &lt;br /&gt;
* Escape scheme for returned data fields (from server): ', | and newline
* Escape scheme for returned data fields (from server): ', | and newline
** Newlines are encoded as &lt;br /&gt;, ' is encoded as ` and | is not allowed in data fields.
** Content newlines are encoded as &lt;br /&gt;, ' is encoded as ` and | is encoded as /.
** Dates are returned in unix time (number of seconds elapsed since January 1, 1970 00:00:00 UTC)


== Basics ==
== Basics ==
=== General ===
=== General ===
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 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 readable version of the result code. Be aware that important data fields may be returned directly after the return code (see: 200,201,209,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 <tt>\n</tt> (no dos linefeed <tt>\r</tt>). The elements of a format string are seperated by a "|" character.
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 <tt>\n</tt> (no dos linefeed <tt>\r</tt>). The elements of a format string are separated by a "|" character.


<tt>{three digit return code} {str return string}\n</tt><br>
<tt>{three digit return code} {str return string}\n</tt><br>
Line 42: Line 45:
* All commands except PING, ENCRYPT, ENCODING, AUTH and VERSION '''requires''' login, meaning that the ''session tag'' must be set (<tt>s=xxxxx</tt>).
* All commands except PING, ENCRYPT, ENCODING, AUTH and VERSION '''requires''' login, meaning that the ''session tag'' must be set (<tt>s=xxxxx</tt>).
* 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.
* 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.
* Due to the length constraints of an UDP package (over PPPoE) 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.
* A client should handle all possible return codes for each command.
** Possible return codes for '''all commands''':
** Possible return codes for '''all commands''':
Line 52: Line 55:
*** 601 ANIDB OUT OF SERVICE - TRY AGAIN LATER
*** 601 ANIDB OUT OF SERVICE - TRY AGAIN LATER
*** 602 SERVER BUSY - TRY AGAIN LATER
*** 602 SERVER BUSY - TRY AGAIN LATER
*** 604 TIMEOUT - DELAY AND RESUBMIT
** Additional return codes for all commands that '''require login''':
** Additional return codes for all commands that '''require login''':
*** 501 LOGIN FIRST
*** 501 LOGIN FIRST
Line 57: Line 61:
*** 506 INVALID SESSION
*** 506 INVALID SESSION


{{eyecatch|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.}}
{{eyecatch|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.}}<br>


{{eyecatch|NOTE:|
{{eyecatch|Note|
While in daily maintenance the AniDB API will reply with
While in daily maintenance the AniDB API will reply with


601 ANIDB OUT OF SERVICE - TRY AGAIN LATER
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.
to all commands. If a client receives such a return value it should wait at least 30 minutes before trying again.}}
}}


=== Server / UDP Connection ===
=== Server / UDP Connection ===
The Client has to send data packets to:
The Client has to send data packets to:
* '''Server:''' api.anidb.info
* '''Server:''' api.anidb.net
* '''Port:''' 9000/UDP
* '''Port:''' 9000/UDP
The servername and port should not be hardcoded into a frontend but should be read from a configuration file.
The servername and port should not be hardcoded into a frontend but should be read from a configuration file.
=== Server Errors ===
=== Server Errors ===
* At any time the API might return a fatal error of the form:
* At any time the API might return a fatal error of the form:
: <tt>6xx ERROR DESCRIPTION</tt>
: <tt>6xx ERROR DESCRIPTION</tt>
* Possible codes are 600-699.
* Possible codes are 600-699.
* Occurances of these errors (except 601) should be reported to [[User:Epoximator|epoximator]].
* Occurrences of these errors (except 601 and 602) should be reported to [[User:Ommina|Ommina]].
{{eyecatch|NOTE:| 6XX messages do not always return the tags given with the command which caused the error!}}
{{eyecatch|Note|6XX messages do not always return the tags given with the command which caused the error!}}


=== Connection Problems ===
=== Connection Problems ===
Line 84: Line 88:


=== Local Port ===
=== 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!)
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/debugging!)


The local port may be hardcoded, however, an option to manually specify another port should be offered.
The local port may be hardcoded, however, an option to manually specify another port should be offered.


'''Note when behind a [http://en.wikipedia.org/wiki/Network_address_translation NAT]/masquerading router:'''<br/>
'''Note when behind a [[Wikipedia:Network address translation|NAT]]/masquerading router:'''<br>
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.
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'' (eg. five, ten 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 the router's deallocation period to prevent a timeout.


The client can decide whether it is behind a NAT router or not by adding <tt>nat=1</tt> 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).
The client can decide whether it is behind a NAT router or not by adding <tt>nat=1</tt> 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 than is necessary to keep NAT connections alive.


=== Flood Protection ===
=== Flood Protection ===
To prevent high server load the UDP API server enforces a strict flood protection policy.
To prevent high server load the UDP API server enforces a strict flood protection policy.
* Short Term:
* Short Term:
** A Client MUST NOT send more than 0.5 packets per second.
** A Client MUST NOT send more than 0.5 packets per second (that's one packet every two seconds, not two packets a second!)
** The server will start to enforce the limit after the first 5 packets have been recieved.
** The server will start to enforce the limit after the first 5 packets have been received.
* Long Term:
* Long Term:
** A Client MUST NOT send more than one packet every 30 seconds over an extended amount of time.
** A Client MUST NOT send more than one packet every four seconds over an extended amount of time.
** ''An extended amount of time'' is not defined. Use common sense.
** ''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.
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.


{{eyecatch|NOTE:| Dropped packets are still taken into account for the packet rate. Meaning if you continuously send packets your client will be banned forever.}}
{{eyecatch|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.
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.


{{eyecatch|NOTE:|
Abusive clients may be banned completely.
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).
{{eyecatch|Note|
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)
If you suddenly stop getting replies from the AniDB API or you normally don't have a notable 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 violating 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 ===
=== Anti Leech Protection ===
Line 122: Line 126:


A client should locally cache FILE/EP/ANIME/GROUP/... info wherever possible for extended amounts of time.
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.)
(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.
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 ===
=== Tag option ===
The api will add a user defined string at the beginning of each reply line seperated with a space, if desired.
The API will add a user defined string at the beginning of each reply line separated with a space, if desired.
* To enable add the <tt>tag={str usertag}</tt> option to a command.
* To enable add the <tt>tag={str usertag}</tt> 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.
* 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.
* Tags are meant to enable a client to handle more than one request/reply at a time.


Usage example:
Usage example:
Line 139: Line 143:
   byebye 203 LOGGED OUT
   byebye 203 LOGGED OUT


{{eyecatch|NOTE:| The tag option is valid for all api commands and is thus not explicitly listed in the description of each command.}}
{{eyecatch|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) ===
=== Data Indexes (fid,aid,eid,gid,lid) ===
* All indexes start at 1 (not 0).
* 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".  
* 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.
* An ID is '''never''' reused. That means after an entry is deleted no new entry will ever have that ID again.
* Mylist IDs (lid) are globally unique, not per-user unique.
* Mylist IDs (lid) are globally unique, not per-user unique.


== Authing Commands ==
== Authing Commands ==
{{eyecatch|NOTE:| _ANY_ command which requires parameters may return: 505 ILLEGAL INPUT OR ACCESS DENIED
{{eyecatch|Note|'''ANY''' command which requires parameters may return: 505 ILLEGAL INPUT OR ACCESS DENIED}}
}}


----
----
=== AUTH: Authing to the AnimeDB ===
=== AUTH: Authing to the AnimeDB ===
'''Command String:'''
'''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}]
* 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}&imgserver=1]


'''Possible Replies:'''
'''Possible Replies:'''
Line 167: Line 170:
* 200 {str session_key} {str ip}:{int2 port} LOGIN ACCEPTED
* 200 {str session_key} {str ip}:{int2 port} LOGIN ACCEPTED
* 201 {str session_key} {str ip}:{int2 port} LOGIN ACCEPTED - NEW VERSION AVAILABLE
* 201 {str session_key} {str ip}:{int2 port} LOGIN ACCEPTED - NEW VERSION AVAILABLE
when imgserver=1
* 200 {str session_key} LOGIN ACCEPTED
{str image server name}
* 201 {str session_key} LOGIN ACCEPTED - NEW VERSION AVAILABLE
{str image server name}


'''Info:'''
'''Info:'''
{{eyecatch|NOTE:| The password is the normal AniDB website password! The password listed in the profile as API Password in only used for the optional encryption feature.}}
{{eyecatch|Note|The password is the normal AniDB website password! The password listed in the profile as API Password in only used for the optional encryption feature.}}
* The ''session_key'' is a String containing only ''a-z,A-Z,0-9'' chars of a length of ''4-8'' characters.
* 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.
: 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.
Line 176: Line 184:
* In case of a '''501 LOGIN FIRST''' message the client should silently resend an auth command and send the failed command 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 '''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 '''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 refers 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.
* 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.
{{eyecatch|NOTE:| A frontend shall expect 501 and 502 messages to be returned on ANY command.}}
{{eyecatch|Note|A frontend shall expect 501 and 502 messages to be returned on ANY command.}}<br>
{{eyecatch|NOTE:| Anidb usernames are always lowercase and may only contain characters (a-z) and numbers (0-9).}}
{{eyecatch|Note|AniDB usernames may only contain characters (a-z,A-Z), numbers (0-9), underscores (_) and hyphens (-).}}
* 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 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 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 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 whether 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 clientname shall be a lower-case 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.
* 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.
: clientname and clientversion might be used by the API to distinguish between different clients and client versions if that should ever become necessary.
{{eyecatch|IMPORTANT:|
{{eyecatch|Important|
* DO NOT use the clientname of another existing client.
* DO NOT use the clientname of an existing client.  If you modify an existing client's code to meet your own needs, create a new client name for yourself.
* ALWAYS increase the clientversion number if you release a new client version.
* ALWAYS increase the clientversion number if you release a new client version.}}
}}
* A Login and its assigned ''session_key'' is valid until the virtual UDP connection times out or until a LOGOUT command is issued.
* 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'''.
* The virtual UDP connection times out if no data was received from the client for '''35 minutes'''.
* A client should issue a UPTIME command once every 30 minutes to keep the connection alive should that be required.
* A client should issue a UPTIME 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 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 issuing 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.
* If it is very likely that another command will be issued shortly (within the next 20 minutes) a client SHOULD keep the current connection open, by not sending a LOGOUT command.
* The client shall notify the user if it recieved a 201 message at login.
{{eyecatch|Important|
* A client should NOT perform a full AUTH / command / LOGOUT cycle for each command it wants to send.  Again, if another command is likely within 20 minutes, remain logged in.}}
* The client shall notify the user if it received 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.
: 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.
* The user should get a pop-up 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!)
: ('''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.
* 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.
{{eyecatch|IMPORTANT:| Make sure your client handels ALL possible AUTH return codes before giving out any versions!}}
{{eyecatch|Important|Make sure your client handles ALL possible AUTH return codes before giving out any versions!}}
* When ''enc=x'' is defined the server will change the encoding used to x.  
* 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 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.
**If not supported then the argument will be silently ignored. Use ENCODING to test what works.
Line 209: Line 217:
**The server will compress (instead of truncating) the datagrams when needed if this option is enabled.
**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.)
**The first two bytes of compressed datagrams will always be set to zero. (So tags should never start with that.)
* Default [http://en.wikipedia.org/wiki/MTU_(networking) ''mtu''] is 1400. Min = 400, Max = 1400.
* Default [[Wikipedia:MTU (networking)|''MTU'']] is 1400. Minimum allowed is 400, maximum 1400, due [[Wikipedia:Point-to-Point Protocol over Ethernet|PPPoE]].


----
----
Line 223: Line 231:
'''Info:'''
'''Info:'''
* This command only works if you are already logged in.
* 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.
* 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.


----
----
=== ENCRYPT: Start Encrypted Session ===
=== 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 [http://en.wikipedia.org/wiki/Advanced_Encryption_Standard 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 [http://en.wikipedia.org/wiki/MD5 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.
Will cause all future messages from the server, except the first (the reply to the ENCRYPT command itself), to be encrypted (128 bit [[Wikipedia:Advanced Encryption Standard|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 [[Wikipedia:MD5|MD5]] hash of a special ''UDP API Key'' (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:'''
'''Command String:'''
Line 242: Line 249:
* ''user'' is the user name.
* ''user'' is the user name.
* ''type'' is the type of encryption; 1 => 128 bit AES (only one defined).
* ''type'' is the type of encryption; 1 => 128 bit AES (only one defined).
* ''API Password'' is the one defined in the profile settings [http://anidb.info/perl-bin/animedb.pl?show=profile page].
* ''API Key'' is the one defined in the {{AniDBLink|profile|profile settings page}}.
* It is not possible to disable the encryption once enabled while staying logged in.
* 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.
** 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.
* 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'').
* The encryption key is md5(api_key_of_user+''salt'').
* Padding of the message needs to be done according to the PKCS5Padding scheme.
* Padding of the message needs to be done according to the PKCS5Padding scheme.


== Notify Commands ==
== Notify Commands ==
These commands offer a way to receive different types of notifications.
=== Introduction ===
Broadly speaking, notifications provide an indication to the client that some event has occurred within the AniDB database.


'''Simple HOWTO:'''
There are three types:
* PUSH to register.
* New file [[Notifications|notification]]. (Only anime type supported.)
* Listen for 271/272 NOTIFICATIONs (not 290).
* New private message notification.
* PUSHACK the NOTIFICATIONs received (with the supplied ids [nid]).
* New buddy event notification.
* 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.
Note that, while a user can subscribe to multiple 'new file' events (see [[Notifications|notifications]]), at present, the UDP API only supports notifications of new files by anime.  New files by group, or new files by producer, are NOT presently supported. Just the same, keeping in mind that the API is designed to potentially support such notifications in the future will help in understanding why some of the commands are structured the way they are.
* 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.
The word "notification" is also used a bit inconsistently in this document.  An AniDB notification is originally a "new file [[Notifications|notification]]". It might be more correct to use the term "event" for the original "happening" and then "notification" as the means to notify the user (client). New-file, new-message, buddy-* and going-down are all events that results in notifications. Only the first two type of events are persistent, though, meaning they exist and remain in the same state until some user action affects them.
 
=== Getting Notifications ===
Clients that wish to receive notifications have two routes available to them.  They are by no means mutually exclusive and selecting one does not imply a client is unable to use commands from another.
 
'''Method One: Polling'''
 
With this method, the client contacts the server at some interval (no more than once every 20 minutes) to see if there are new file notifications waiting.  If there are, the client can the get further details of the files in question.  This is analogous to checking an email server every half hour to see if new email has arrived.


=== PUSH: UDP Notification Registration ===
Its principal advantage is that it is easy to design and code.  Blocking sockets are sufficient as the client can expect the reply received to correspond with the command sent.
'''Command String:'''
* PUSH notify={bool push_file_added_notifications}&msg={bool push_msg_added_notifications}[&buddy={bool push_buddy_event_notifications}]


'''Possible Replies:'''
The disadvantage of this approach is that it introduces a delay and some uncertainty in receiving notifications. If, for example, the user clears the notification on the website before the client collects it, the client will not learn of the new file.  Similarly, if the user does not dismiss notifications via the site, the client will have an increasing amount of stale data to work though.  Finally, notifications cleared by the client also clears them from the website, so users will need to be made aware of what is going on.
* 270 NOTIFICATION ENABLED
  OR (if both values are 0)
* 370 NOTIFICATION DISABLED


'''Note:'''
A polling HOWTO:
* 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.
* A client which has registered to recieve UDP notification packets should:
** Use PING to keep the connection alive (< 30 min).
** Use UPTIME to ensure that the session is OK (>= 30 min).


====Notification Packet Format====
* Use NOTIFY (no more than once every 20 minutes) to get the number of pending notifications
'''File Added Notify:'''
* IF there are new notifications pending, use NOTIFYLIST to get a list of notification types and associated IDs.
* Use NOTIFYGET to receive a notification, supplying the ID provided by NOTIFYLIST
* Use NOTIFYACK to acknowledge a notification, supplying the ID provided by NOTIFYLIST (if desired)


  271 {int4 notify_packet_id} NOTIFICATION
{{eyecatch|Note|The ID supplied by NOTIFYLIST will be the ID of the affected notification type.  Since, at present, only the anime type is supported, this value is always an aid.  In the future, it may represent a group or producer ID.  In these cases, the str '''type''' value will indicate what entity the ID represents.}}
  {int4 aid}|{int4 date}|{int4 count}|{str animetitle}


* aid is the id of the affected anime
'''Method Two: Server PUSH'''
* 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:'''
With this method, the server takes the active role in advising the client that a new file has arrived.  The client must register with the server to receive further advice information, and will be responsible for keeping the login session from timing out, and any NAT router ports open.  The UDP packet is sent to the ip and port from which the AUTH command was received.


  272 {int4 notify_packet_id} NOTIFICATION
This method compensates for the disadvantages of the polling method, but is more difficult to code.  Blocking sockets are no longer an option, nor can a client make any assumptions that an incoming packet will necessarily be a reply to the last command sent.  The tag option may be helpful here.
  {int2 type}|{int4 date}|{int4 senderuid}|{str sendername}|{str subject}|{str body}|{int mid}


* type is the type of the message (0=normal msg, 1=annonymous, 2=system msg, 3=mod msg)
A PUSH HOWTO:
* 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
* body is message body (can be truncated)
* mid is message id and can be used with NOTIFYACK


'''Buddy Event Notify:'''
* PUSH to register your client session.
  273 {int4 notify_packet_id} NOTIFICATION
* Listen for 720-799 NOTIFICATIONs ('''not 290''').
  {int4 buddy uid}|{int2 event type}
* Use PUSHACK to to acknowledge the notification using the nid supplied with NOTIFICATION
* Possible event types:
* Use NOTIFYGET to receive a notification, suppling the relid provided by NOTIFICATION (NOT the packet ID)
** 0 => LOGIN
* Use NOTIFYACK to acknowledge a notification, suppling the relid provided by NOTIFICATION (if desired)
** 1 => LOGOUT
* Use UPTIME (with an interval between 30 and 35 minutes) to keep login session valid
** 2 => ACCEPTED
** 3 => ADDED


'''Going Down Event Notify:'''
It is probably a good idea to use tags to separate NOTIFICATIONs from the other communication. NOTIFICATIONs will '''never''' have tags.
  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.
=== PUSH: UDP Notification Registration ===
* 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).
Register your client as an observer for AniDB notification events for the current user. If you are registered for one or more event types the AniDB server will send an UDP packet (format see below) on each change which affects the current user.
* 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:'''
'''Command String:'''
* PUSHACK nid={int4 notify_packet_id}
* PUSH notify={boolean on_new_file}&msg={boolean on_new_private_message}[&buddy={boolean on_buddy_event}]


'''Possible Replies:'''
'''Possible Replies:'''
* 280 PUSHACK CONFIRMED
* 270 NOTIFICATION ENABLED
* 380 NO SUCH PACKET PENDING
OR (if both values are 0)
* 370 NOTIFICATION DISABLED


'''Info:'''
'''Info:'''
* This command only works if you are logged in.
* A client which has registered to receive UDP notification packets must:
*see: '''PUSH'''
** Issue a PUSHACK command for each notification received with ''notify_packet_id'' provided in the notification packet.
** Use PING to keep the connection alive (< 30 min).
** Use UPTIME to ensure that the session is OK (>= 30 min).
* Every notification generated is resent 3 times unless acknowledged. After that the client is logged out.


----
=== NOTIFY: Notifications ===
=== NOTIFY: Notifications ===
Get number of pending notifications (and number of online buddies).
'''Command String:'''
'''Command String:'''
* NOTIFY [buddy=1]
* NOTIFY [buddy=1]
Line 340: Line 332:
'''Possible Replies:'''
'''Possible Replies:'''
* 290 NOTIFICATION
* 290 NOTIFICATION
: {int4 pending_notifies}|{int4 pending_msgs}
: {int4 pending_file_notifications}|{int4 number_of_unread_messages}
when ''buddy=1''
when ''buddy=1''
* 290 NOTIFICATION
* 290 NOTIFICATION
: {int4 pending_notifies}|{int4 pending_msgs}|{int4 number_of_online_buddys}
: {int4 pending_file_notifications}|{int4 number_of_unread_messages}|{int4 number_of_online_buddies}


'''Info:'''
'''Info:'''
* This command only works if you are logged in.
* If the client did send a NOTIFY within the last 35 minutes and it was confirmed by AniDB then receiving 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.
* ''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.
* 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.
* There is no command to retrieve missed PUSH Notifications.
{{eyecatch|NOTE:| This command MUST NOT be issued more than once every 20 minutes.}}
{{eyecatch|Note|This command MUST NOT be issued more than once every 20 minutes.}}


----
----
=== NOTIFYLIST: List Notification/Message IDs ===
List id of all pending (not acknowledged) ''new private message'' and ''new file'' notifications. Buddy events cannot be acknowledged.


=== NOTIFYLIST: List Notification/Message IDs ===
'''Command String:'''
'''Command String:'''
* NOTIFYLIST
* NOTIFYLIST
Line 366: Line 356:


'''Info:'''
'''Info:'''
* This command only works if you are logged in.
* type is:
* type is:
: M for message entries
: M for message entries
: N for notification entries
: N for notification entries
*id is the identifier for the notification/message as required by NOTIFYGET.
* id is the identifier for the notification/message as required by NOTIFYGET. For messages it is the actual message id, for notifications it is the id of the related type; anime, group or producer. Since only file notifications related to anime is implemented atm, it is the anime id (aid).
* NOTIFYLIST returns one line per entry, if no entries are available only the first line of the reply is returned.
* NOTIFYLIST returns one line per entry, if no entries are available only the first line of the reply is returned.
{{eyecatch|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.}}
{{eyecatch|Note|This command MUST NOT be issued regularly but should only be triggered by either a push message received by the client or a reply to a NOTIFY command which tells you that there are messages/notifications waiting.}}


----
----
=== NOTIFYGET: Get Notification/Message ===
=== NOTIFYGET: Get Notification/Message ===
Receive private message or file notification.
'''Command String:'''
'''Command String:'''
* NOTIFYGET type={str type}&id={int4 id}
* NOTIFYGET type={str type}&id={int4 id}
Line 386: Line 377:
when type = N
when type = N
* 293 NOTIFYGET
* 293 NOTIFYGET
: {int4 aid}|{int4 type}|{int2 count}|{int4 date}|{str anime_name}
: {int4 relid}|{int4 type}|{int2 count}|{int4 date}|{str relidname}|{str fids}
* 393 NO SUCH ENTRY
* 393 NO SUCH ENTRY


'''Info:'''
'''Info:'''
* This command only works if you are logged in.
* type is:
* type is:
: M for message entries
: M for message entries
: N for notification entries
: N for notification entries
* id is the identifier for the notification/message as required by NOTIFYGET.
* id is the identifier for the notification/message as given by NOTIFYLIST (or ''relid'' from 271 NOTIFICATION and mid from 272 NOTIFICATION)
* for message entries (M):
* for message entries (M):
: date is the time of the event (in seconds since 1.1.1970)
: 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)
: type is the type of the message (0=normal msg, 1=annonymous, 2=system msg, 3=mod msg)
* for notification entries (N):
* for notification entries (N):
: aid is the id of the affected anime
: relid is the id of the related type (anime)
: type is the notification type (0=all, 1=new, 2=group)
: relname is the name of the related type (anime)
: count is the number of events pending for this anime
: type is the notification type (0=all, 1=new, 2=group, 3=complete)
: count is the number of events pending for this subscription
: date is the time of the event (in seconds since 1.1.1970)
: date is the time of the event (in seconds since 1.1.1970)
: fids is a comma separated list with the affected file ids


----
----
=== NOTIFYACK: Acknowledge Notification/Message ===
This command will mark a message read or clear a ''new file'' notification. Buddy events are not acknowledgeable.


=== NOTIFYACK: Acknowledge Notification/Message ===
'''Command String:'''
'''Command String:'''
* NOTIFYACK type={str type}&id={int4 id}
* NOTIFYACK type={str type}&id={int4 id}
Line 419: Line 412:


'''Info:'''
'''Info:'''
* This command only works if you are logged in.
* This command will mark a message read or clear a notification.
* type is:
* type is:
: M for message entries
: M for message entries
: N for notification entries
: N for notification entries
====Notification Packet Format====
'''New File Notify:'''
  720 {int4 notify_packet_id} NOTIFICATION - NEW FILE
  {int4 fidlist}|{int2 reltype}|{int2 priority}
* fidlist is a comma separated list of file ids
* reltype is: 1 = anime, 2 = group, 3 = producer
* priority is: 0 = low, 1 = medium, 2 = high
* new file notifications are created as a batch, so it is not unusual to get several new files for a particular anime at once.  It is in this case that a comma separated list of fids will be returned
{{eyecatch|Note|Group (and producer) related file notifications are not implemented yet.}}
'''New Private Message Notify:'''
  794 {int4 notify_packet_id} NOTIFICATION - NEW MESSAGE
  {int2 type}|{int4 date}|{int4 sent_by_uid}|{str sent_by_name}|{str subject}|{str body}|{int mid}
* type is the type of the message (0=normal msg, 1=anonymous, 2=system msg, 3=mod msg)
* date is the time the message was sent (in seconds since 1.1.1970)
* sender uid/sender name are the user id and user name of the sender
* subject is the message subject
* body is message body (can be truncated)
* mid is message id and can be used with NOTIFYACK
'''Buddy Event Notify:'''
  753 {int4 notify_packet_id} NOTIFICATION - BUDDY
  {int4 buddy uid}|{int2 event type}
* Possible event types:
** 0 => LOGIN
** 1 => LOGOUT
** 2 => ACCEPTED
** 3 => ADDED
'''Going Down Event Notify:'''
  799 {int4 notify_packet_id} NOTIFICATION - SHUTTING DOWN
  {int4 time offline}|{int4 comment}
* Clients with any notification on will receive the SHUTTING DOWN 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 ===
Used to acknowledge notification packets (720-799). A client must be prepared to issue this command before using '''PUSH'''.
'''Command String:'''
* PUSHACK nid={int4 notify_packet_id}
'''Possible Replies:'''
* 701 PUSHACK CONFIRMED
* 702 NO SUCH PACKET PENDING
'''Info:'''
* See: '''PUSH'''
== Notification Commands ==
=== NOTIFICATIONADD: Add Anime or Group to Notify List ===
'''Command String:'''<br>
by anime id:
* NOTIFICATIONADD aid={int4 aid}&type={int2 type}&priority={int2 priority}
by group id:
* NOTIFICATIONADD gid={int4 gid}&type={int2 type}&priority={int2 priority}
<br>
'''Possible Replies:'''
* 246 NOTIFICATION ITEM ADDED
: {int4 notification id}
* 248 NOTIFICATION ITEM UPDATED
: {int4 notification id}
* 399 NO CHANGES
<br>
'''Info:'''
* ''Priority'' values are 0: low, 1: medium, 2: high
* ''Type'' values are 0: all, 1: new, 2: group, 3: complete
=== NOTIFICATIONDEL: Remove Anime or Group from Notify List ===
'''Command String:'''<br>
by anime id:
* NOTIFICATIONDEL aid={int4 aid}
by group id:
* NOTIFICATIONDEL gid={int4 gid}
<br>
'''Possible Replies:'''
* 247 NOTIFICATION ITEM DELETED
: {int4 notification_table}|{int4 relid}
* 324 NO SUCH NOTIFICATION ITEM
<br>
'''Info:'''
* ''notification_table'' values are 1: anime, 2: group
* ''relid'' value matches the aid/gid supplied


== Buddy Commands ==
== Buddy Commands ==
Line 438: Line 531:


----
----
=== BUDDYDEL: Remove a user from Buddy List ===
=== BUDDYDEL: Remove a user from Buddy List ===
'''Command String:'''
'''Command String:'''
Line 447: Line 539:


----
----
=== BUDDYACCEPT: Accept user as Buddy ===
=== BUDDYACCEPT: Accept user as Buddy ===
'''Command String:'''
'''Command String:'''
Line 457: Line 548:


----
----
=== BUDDYDENY: Deny user as Buddy ===
=== BUDDYDENY: Deny user as Buddy ===
'''Command String:'''
'''Command String:'''
Line 467: Line 557:


----
----
=== BUDDYLIST: Retrieve Buddy List ===
=== BUDDYLIST: Retrieve Buddy List ===
'''Command String:'''
'''Command String:'''
Line 482: Line 571:


----
----
=== BUDDYSTATE: Retrieve Buddy States===
=== BUDDYSTATE: Retrieve Buddy States===
'''Command String:'''
'''Command String:'''
Line 501: Line 589:
'''Command String:'''<br>
'''Command String:'''<br>
by aid
by aid
* ANIME aid={int4 id}[&acode={int4}]
* ANIME aid={int4 id}[&amask={hexstr}]
by name
by name
* ANIME aname={str anime name}[&acode={int4}]
* ANIME aname={str anime name}[&amask={hexstr}]


'''Possible Replies:'''
'''Possible Replies:'''
If no ''amask'' is provided:
* 230 ANIME
* 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}
: {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}
Line 511: Line 601:


'''Info:'''
'''Info:'''
* Fields are returned in the same order they appear in the ''amask'' field list: byte 1, bit 7 first
* Synonyms and short names are separated with '
* Synonyms and short names are separated with '
* Category names are separated with ',' and ordered by weight (desc).
* Category fields are separated with ',' and ordered by weight (desc). ''However'', be aware that categories are no longer used nor updated internally, and category responses are only returned to avoid breaking older clients.  Use tags as a replacement.
* No support for genres.
* By name: must be perfect match of romaji/kanji/english/other/synonym/short name.
* 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.
* 'Producer id list' and 'producer name list' match the data returned by the former producer bits (but using the revised creator ids)
* Date flags are used to indicated an unknown value (unknown month, day, year)
* ''dateflags'' values:
** bit0 set == Startdate, Unknown Day
** bit1 set == Startdate, Unknown Month, Day
** bit2 set == Enddate, Unknown Day
** bit3 set == Enddate, Unknown Month, Day
** bit4 set == AirDate in the Past/Anime has ended
** bit5 set == Startdate, Unknown Year
** bit6 set == Enddate, Unknown Year
 
* '''Note:''' The character id list is the first data to be truncated if needed. And then: tag list, synonym list, short name list. This applies to the FILE command too.
* Selecting an 'unused' or 'reserved' bit will return an "illegal input" (505) response.
 
<table border="0" cellpadding="0" cellspacing="2">
<tr><td colspan="5" align="center"><b>amask</b></td></tr>
<tr>
  <td align="center"><b>Byte 1</b></td>
  <td align="center"><b>Byte 2</b></td>
  <td align="center"><b>Byte 3</b></td>
  <td align="center"><b>Byte 4</b></td>
  <td align="center"><b>Byte 5</b></td>
  <td align="center"><b>Byte 6</b></td>
  <td align="center"><b>Byte 7</b></td>
</tr>
<tr>
  <td>
  <table>
    <tr>
    <td><b>Bit</b></td>
    <td align="right"><b>Dec</b></td>
    <td><b>Data Field</b></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>int aid</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>int dateflags</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>str year</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>str type</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>str related aid list</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>str related aid type</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td><i>retired</i></td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td><i>retired</i></td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td><b>Bit</b></td>
    <td align="right"><b>Dec</b></td>
    <td><b>Data Field</b></td>
    </tr>
    <tr>
    <td>7</td>
    <td align="right">128</td>
    <td>str romaji name</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>6</td>
    <td align="right">64</td>
    <td>str kanji name</td>
    </tr>
    <tr>
    <td>5</td>
    <td align="right">32</td>
    <td>str english name</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>4</td>
    <td align="right">16</td>
    <td>str other name</td>
    </tr>
    <tr>
    <td>3</td>
    <td align="right">8</td>
    <td>str short name list</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>2</td>
    <td align="right">4</td>
    <td>str synonym list</td>
    </tr>
    <tr>
    <td>1</td>
    <td align="right">2</td>
    <td><i>retired</i></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>0</td>
    <td align="right">1</td>
    <td><i>retired</i></td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td><b>Bit</b></td>
    <td align="right"><b>Dec</b></td>
    <td><b>Data Field</b></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>int4 episodes</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>int4 highest episode number</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>int4 special ep count</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>int air date</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>int end date</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>str url</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>str picname</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td><i>retired</i></td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td><b>Bit</b></td>
    <td align="right"><b>Dec</b></td>
    <td><b>Data Field</b></td>
    </tr>
    <tr>
    <td>7</td>
    <td align="right">128</td>
    <td>int4 rating</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>6</td>
    <td align="right">64</td>
    <td>int vote count</td>
    </tr>
    <tr>
    <td>5</td>
    <td align="right">32</td>
    <td>int4 temp rating</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>4</td>
    <td align="right">16</td>
    <td>int temp vote count</td>
    </tr>
    <tr>
    <td>3</td>
    <td align="right">8</td>
    <td>int4 average review rating</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>2</td>
    <td align="right">4</td>
    <td>int review count</td>
    </tr>
    <tr>
    <td>1</td>
    <td align="right">2</td>
    <td>str award list</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>0</td>
    <td align="right">1</td>
    <td>bool is 18+ restricted</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td><b>Bit</b></td>
    <td align="right"><b>Dec</b></td>
    <td><b>Data Field</b></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td><i>retired</i></td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>int ANN id</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>int allcinema id</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>str AnimeNfo id</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>str tag name list</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>int tag id list</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>int tag weight list</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td>int date record updated</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td><b>Bit</b></td>
    <td align="right"><b>Dec</b></td>
    <td><b>Data Field</b></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>int character id list</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td><i>retired</i></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td><i>retired</i></td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td><i>retired</i></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>unused</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td>unused</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td><b>Bit</b></td>
    <td align="right"><b>Dec</b></td>
    <td><b>Data Field</b></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>int4 specials count</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>int4 credits count</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>int4 other count</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>int4 trailer count</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>int4 parody count</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>unused</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td>unused</td>
    </tr>
  </table>
  </td>
</tr>
</table>
 
 
'''Related aid type (Byte 1, Bit 2):'''
<pre>
value      meaning
 
    1      sequel
    2      prequel
  11      same setting
  12      alternative setting
  32      alternative version
  41      music video
  42      character
  51      side story
  52      parent story
  61      summary
  62      full story
  100      other
</pre>
 
'''Examples:''' (note that the given amask gives the same result as the default request)
  > ANIME aid=1&amask=b2f0e0fc000000&s=xxxxx
  < 230 ANIME
    1|1999-1999|TV Series|Space,Future,Plot Continuity,SciFi,Space Travel,Shipboard,Other Planet,Novel,Genetic Modification,Action,Romance,Military,Large Breasts,Gunfights,Adventure,Human Enhancement,Nudity|Seikai no Monshou|星界の紋章|Crest of the Stars||13|13|3|853|3225|756|110|875|11
 
 
----
 
=== ANIMEDESC: Retrieve Anime Description ===
'''Command String:'''<br>
by aid
* ANIMEDESC aid={int4 id}&part={int4 partno}
 
'''Possible Replies:'''
* 233 ANIMEDESC
: {int4 current part}|{int4 max parts}|{str description}
* 330 NO SUCH ANIME
* 333 NO SUCH DESCRIPTION
 
'''Info:'''
* The maximum length of the anime description is roughly 5000 characters, but the maximum length of a UDP packet is 1400 bytes
* Multiple calls to ANIMEDESC may be necessary to retrieve the complete text, retrieving separate 1400 byte parts with each call
* ''part'' is zero-based
* '''Note:''' No support, at present, for retrieving descriptions by title.  ''aid'' only


'''acode:'''
{| cellpadding="0" align="center"
! width="40"|Bit
! width="80"|Decimal
! width="160"|Data field
! width="50"|-
! width="40"|Bit
! width="120"|Decimal
! width="160"|Data field
|- style="background-color: #eee;"
|0 ||1 || int4 aid || || 16 || 65536 || str url
|-
|1 ||2 || int4 episodes || || 17 || 131072 || str picname
|- style="background-color: #eee;"
|2 ||4 || int4 normal ep count || || 18 || 262144 || str year
|-
|3 ||8 || int4 special ep count ||  || 19 || 524288 || str type
|- style="background-color: #eee;"
|4 ||16 || int4 rating || || 20 || 1048576 || str romaji name
|-
|5 ||32 || int4 vote count || || 21 || 2097152 || str kanji name
|- style="background-color: #eee;"
|6 ||64 || int4 temp rating || || 22 || 4194304 || str english name
|-
|7 ||128 || int4 temp vote count || || 23 || 8388608 || str other name
|- style="background-color: #eee;"
|8 ||256 || int4 average review rating || || 24 || 16777216 || str short name list
|-
|9 ||512 || int4 review count || || 25 || 33554432 || str synonym list
|- style="background-color: #eee;"
|10 ||1024 || int4 air date || || 26 || 67108864 || str category list
|-
|11 ||2048 || int4 end date || || 27 || 134217728 || str related aid list
|- style="background-color: #eee;"
|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
|- style="background-color: #eee;"
|14 ||16384 || int4 allcinema id || || 30 || 1073741824 || str award list
|-
|15 ||32768 || str animenfo id || || 31 || -2147483648 || reserved (all)
|}


'''Examples:''' (html escaped code intended)
'''Examples:''' (html escaped code intended)
   > ANIME aname=tmm&s=xxxxx
   > ANIMEDESC aid=3169&part=0&s=xxxxx
   < 230 ANIME
   < 233 ANIMEDESC
  161|52|50|0|715|57|777|35|816|1|2002-2003|TV|Tokyo Mew Mew|&#26481;&#20140;&#12511;&#12517;&#12454;&#12511;&#12517;&#12454;||||TMM'mew|Cat Girls
    0|1|As summer break arrives for the students, Jun Sakurada is busily studying on his own in the library, making up for time lost <cut>
 
----
=== CALENDAR: Get Upcoming Titles ===
Returns the anime ids of the 25 most recently aired / released anime, directly followed by the next 25 anime due to be aired / released, ordered by start date.
 
'''Command String:'''
* CALENDAR
 
'''Possible Replies:'''
* 297 CALENDAR
{int aid}|{int startdate}|{int dateflags}/n
 
..repeated n times
 
* 397 CALENDAR EMPTY
 
'''Info:'''
* Takes no parameters (other than the session string)
* Titles returned are filtered by the 'show adult' preference of the logged in user.  That is, users who have elected to hide adult content will have it hidden here as well.
* Do not depend on the command always returning exactly 50 titles; there may not always be 25 future titles pending, depending on the user's 'adult' preferences, and the date in relation to the relation to the current anime season.
* Date flags are used to indicated an unknown value (unknown month, day, year)
* ''dateflags'' values:
** bit0 set == Startdate, Unknown Day
** bit1 set == Startdate, Unknown Month, Day
** bit2 set == Enddate, Unknown Day
** bit3 set == Enddate, Unknown Month, Day
** bit4 set == AirDate in the Past/Anime has ended
** bit5 set == Startdate, Unknown Year
** bit6 set == Enddate, Unknown Year


  > ANIME aname=&#12490;&#12523;&#12488;&s=xxxxx
  < 230 ANIME
  239|0|140|2|1000|10|855|3750|803|36|2002-2005|TV|Naruto|&#12490;&#12523;&#12488;||&#1504;&#1488;&#1512;&#1493;&#1496;&#1493;|NARUTO'&#1606;&#1575;&#1585;&#1608;&#1578;&#1608;|naruto tv'ntv|Action,Shounen,Past,...(cut)


----
----
=== CHARACTER: Get Character Information ===
Returns character details associated with a given character ID, including associated anime ids, episode ids, and seiyuu.
'''Command String:'''
* CHARACTER charid={int characterid}
'''Possible Replies:'''
* 235 CHARACTER
: {int charid}|{str character name kanji}|{str character name transcription}|{str pic}|{anime blocks}|{int episode list}|{int last update date}|{int2 type}|{str gender}
: An 'anime block' is {int anime id},{int appearance},{int creatorid},{boolean is_main_seiyuu} repeated as many times as necessary, separated by a single quote ( ' ).
* 335 NO SUCH CHARACTER
'''Info:'''
* If no seiyuu is associated with the character for a given aid, the 'creatorid' and 'is_main_seiyuu' fields will be empty, but the commas will remain.
* An empty episode list is "undefined": no episode values have been added.
* ''appearance'' values: 0='appears in', 1='cameo appearance in', 2='main character in', 3='secondary cast in'
* ''type'' can be one of: (Note: this is subject to changes so don't rely on this mapping)
** 1 => 'Character'
** 2 => 'Mecha'
** 3 => 'Organisation'
** 4 => 'Vessel'
* ''gender'' can be one of: (Note: this is subject to changes so don't rely on this mapping)
** "M" => 'Male'
** "F" => 'Female'
** "I" => 'Intersexual'
** "D" => 'Dimorphic'
** "-" => 'none/does not apply'
** "?" => 'unknown'
'''Example:'''
  CHARACTER charid=488&s=DChan
  235 CHARACTER
  488|ニコ・ロビン|Nico Robin|14789.jpg|4097,2,1900,1'69,2,1901,0'6199,0,1900,1'5691,0,1900,1'2644,0,,'4851,0,1900,1||1236938094
=== CREATOR: Get Creator Information ===
'''Command String:'''
* CREATOR creatorid={int creatorid}
'''Possible Replies:'''
* 245 CREATOR
: {int creatorid}|{str creator name kanji}|{str creator name transcription}|{int type}|{str pic_name}|{str url_english}|{str url_japanese}|{str wiki_url_english}|{str wiki_url_japanese}|{int last update date}
* 345 NO SUCH CREATOR
'''Info:'''
* ANIME AMASK byte6, bit5
* ''type'' values: 1='person', 2='company', 3='collaboration'
Example:
  245 CREATOR
  718|GAINAX|Gainax|2|10092.png||http://www.gainax.co.jp/|Gainax|Gainax|1237048093
=== EPISODE: Retrieve Episode Data ===
=== EPISODE: Retrieve Episode Data ===
'''Command String:'''<br>
'''Command String:'''<br>
by eid
by eid
* EPISODE eid={int4 eid}
* EPISODE eid={int eid}
by anime and episode number
by anime and episode number
* EPISODE aname={str anime name}&epno={int4 episode number}
* EPISODE aname={str anime name}&epno={int4 episode number}
* EPISODE aid={int4 anime id}&epno={int4 episode number}
* EPISODE aid={int anime id}&epno={int4 episode number}


'''Possible Replies:'''
'''Possible Replies:'''
* 240 EPISODE
* 240 EPISODE
: {int4 eid}|{int4 aid}|{int4 length}|{int4 rating}|{int4 votes}|{str epno}|{str eng}|{str romaji}|{str kanji}
: {int eid}|{int aid}|{int4 length}|{int4 rating}|{int votes}|{str epno}|{str eng}|{str romaji}|{str kanji}|{int aired}|{int type}
* 340 NO SUCH EPISODE
* 340 NO SUCH EPISODE


'''Info:'''
'''Info:'''
* length is in minutes
* 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).
* 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).
* The ''type'' is the raw episode type, used to indicate numerically what the special character will be
** 1: regular episode (no prefix), 2: special ("S"), 3: credit ("C"), 4: trailer ("T"), 5: parody ("P"), 6: other ("O")


'''Examples:''' (html escaped code intended)
'''Examples:''' (html escaped code intended)
Line 594: Line 1,142:
   > EPISODE aname=Seikai no Monshou&epno=2&s=xxxxx
   > EPISODE aname=Seikai no Monshou&epno=2&s=xxxxx
   < 240 EPISODE
   < 240 EPISODE
   2|1|24|750|2|02|Kin of the Stars|Hoshi-tachi no Kenzoku|??????
   2|1|24|750|2|02|Kin of the Stars|Hoshi-tachi no Kenzoku|??????|1295059229|1


----
----
=== FILE: Retrieve File Data ===
=== FILE: Retrieve File Data ===
'''Command String:'''<br>
'''Command String:'''<br>
by fid:
by fid:
* FILE fid={int4 id}[&fcode={int4}&acode={int4}]
* FILE fid={int4 id}&fmask={hexstr fmask}&amask={hexstr amask}
by size+ed2k hash:
by size+ed2k hash:
* FILE size={int8 size}&ed2k={str ed2khash}[&fcode={int4}&acode={int4}]
* FILE size={int8 size}&ed2k={str ed2khash}&fmask={hexstr fmask}&amask={hexstr amask}
by anime, group and epno
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}&gname={str group name}&epno={int4 episode number}&fmask={hexstr fmask}&amask={hexstr amask}
* FILE aname={str anime name}&gid={int4 group id}&epno={int4 episode number}[&fcode={int4}&acode={int4}]
* FILE aname={str anime name}&gid={int4 group id}&epno={int4 episode number}&fmask={hexstr fmask}&amask={hexstr amask}
* FILE aid={int4 anime id}&gname={str group name}&epno={int4 episode number}[&fcode={int4}&acode={int4}]
* FILE aid={int4 anime id}&gname={str group name}&epno={int4 episode number}&fmask={hexstr fmask}&amask={hexstr amask}
* FILE aid={int4 anime id}&gid={int4 group id}&epno={int4 episode number}[&fcode={int4}&acode={int4}]
* FILE aid={int4 anime id}&gid={int4 group id}&epno={int4 episode number}&fmask={hexstr fmask}&amask={hexstr amask}


'''Possible Replies:'''
'''Possible Replies:'''
Line 619: Line 1,168:


'''Info:'''
'''Info:'''
* fid, aid, eid, gid are the unique ids for the file, anime, ep, group entries at anidb.
* 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.
: You can use those to create links to the corresponding pages at AniDB.
* anidbfilename is the anidb filename for the file.
* 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.
: 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.
* fmask and amask are hexidecimal strings where each bit corresponds to a data field related to the specified file (see below). The data list received is sorted and returned in the same order as the tables: top to bottom, left to right, with fmask preceding amask. There is '''no''' provision to retrieve all fields.  Further, requesting a 'unusued' or 'reserved' bit will return an "illegal input" error.
* fid is always returned as the first value, regardless of what masks are provided.
* Only the first matching file is returned when aname, gname and epno is used.
* Only the first matching file is returned when aname, gname and epno is used.
 
* "audio codec" and "audio bitrate" will return multiple values if there are multiple audio streams present in the file.  Values will be separated by a single quote. 
* For byte 1, bit 2 (other episodes): episode IDs will be followed by an integer '''percentage''' that indicate the percentage of the related episode this file covers. Typically 100%, there are cases where it will be 50, 30, or other values.  This value provides no indication where, within an episode, the file represents.  That is, 50% could mean the file covers the first half of the episode, the second half, or some 50% range in between.
'''State:'''
'''State:'''
<pre>
<pre>
bit / int value meaning
bit / int value meaning
1 / 1 FILE_CRCOK: file matched official crc (displayed with green background in anidb)
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)
2 / 2 FILE_CRCERR: file DID NOT match official CRC (displayed with red background in AniDB)
3 / 4 FILE_ISV2: file is version 2
3 / 4 FILE_ISV2: file is version 2
4 / 8 FILE_ISV3: file is version 3
4 / 8 FILE_ISV3: file is version 3
Line 639: Line 1,190:


examples:
examples:
state ==== 9 ==> FILE_CRCOK+FILE_ISV3 ==> file matched official crc and is version 3
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 ==== 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 ==== 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 ==== 1 ==> FILE_CRCOK ==> file matched official CRC and is version 1
state ==== 8 ==> FILE_ISV3 ==> file was not crc checked and is version 3
state ==== 8 ==> FILE_ISV3 ==> file was not CRC checked and is version 3
</pre>
</pre>


'''fcode:'''
<table border="0" cellpadding="0" cellspacing="2">
{| cellpadding="0" align="center"
<tr><td colspan="4" align="center">'''fmask:'''</td></tr>
! width="40"|Bit
<tr>
! width="80"|Decimal
  <td align="center">'''Byte 1'''</td>
! width="160"|Data field
  <td align="center">'''Byte 2'''</td>
! width="50"|-
  <td align="center">'''Byte 3'''</td>
! width="40"|Bit
  <td align="center">'''Byte 4'''</td>
! width="120"|Decimal
  <td align="center">'''Byte 5'''</td>
! width="160"|Data field
</tr>
|- style="background-color: #eee;"
<tr>
|0 ||1 || not used || || 16 || 65536 || str dub language
  <td>
|-
  <table>
|1 ||2 || int4 aid || || 17 || 131072 || str sub language
    <tr>
|- style="background-color: #eee;"
    <td>'''Bit'''</td>
|2 ||4 || int4 eid || || 18 || 262144 || str quality
    <td align="right">'''Dec'''</td>
|-
    <td>'''Data Field'''</td>
|3 ||8 || int4 gid ||  || 19 || 524288 || str source
    </tr>
|- style="background-color: #eee;"
    <tr bgcolor="#eeeeee">
|4 ||16 || int4 lid || || 20 || 1048576 || str audio codec
    <td>7</td>
|-
    <td align="right">128</td>
|5 ||32 || not used || || 21 || 2097152 || int4 audio bitrate
    <td>unused</td>
|- style="background-color: #eee;"
    </tr>
|6 ||64 || not used || || 22 || 4194304 || str video codec
    <tr>
|-
    <td>6</td>
|7 ||128 || not used || || 23 || 8388608 || int4 video bitrate
    <td align="right">64</td>
|- style="background-color: #eee;"
    <td>int4 aid</td>
|8 ||256 || int2 state || || 24 || 16777216 || str video resolution
    </tr>
|-
    <tr bgcolor="#eeeeee">
|9 ||512 || int8 size || || 25 || 33554432 || str file type (extension)
    <td>5</td>
|- style="background-color: #eee;"
    <td align="right">32</td>
|10 ||1024 || str ed2k || || 26 || 67108864 || int4 length in seconds
    <td>int4 eid</td>
|-
    </tr>
|11 ||2048 || str md5 || || 27 || 134217728 || str description
    <tr>
|- style="background-color: #eee;"
    <td>4</td>
|12 ||4096 || str sha1 || || 28 || 268435456 || not used
    <td align="right">16</td>
|-
    <td>int4 gid</td>
|13 ||8192 || str crc32 || || 29 || 536870912 || not used
    </tr>
|- style="background-color: #eee;"
    <tr bgcolor="#eeeeee">
|14 ||16384 || not used || || 30 || 1073741824 || str anidb file name
    <td>3</td>
|-
    <td align="right">8</td>
|15 ||32768 || not used || || 31 || -2147483648 || not used
    <td>int4 mylist id</td>
|}
    </tr>
'''acode:'''
    <tr>
{| cellpadding="0" align="center"
    <td>2</td>
! width="40"|Bit
    <td align="right">4</td>
! width="80"|Decimal
    <td>list other episodes</td>
! width="160"|Data field
    </tr>
! width="50"|-
    <tr bgcolor="#eeeeee">
! width="40"|Bit
    <td>1</td>
! width="120"|Decimal
    <td align="right">2</td>
! width="160"|Data field
    <td>int2 IsDeprecated</td>
|- style="background-color: #eee;"
    </tr>
|0 ||1 || str group name || || 16 || 65536 || int4 anime total episodes
    <tr>
|-
    <td>0</td>
|1 ||2 || str group short name || || 17 || 131072 || int4 last episode nr (highest, not special)
    <td align="right">1</td>
|- style="background-color: #eee;"
    <td>int2 state</td>
|2 ||4 || not used || || 18 || 262144 || str year
    </tr>
|-
  </table>
|3 ||8 || not used ||  || 19 || 524288 || str type
  </td>
|- style="background-color: #eee;"
  <td>
|4 ||16 || not used || || 20 || 1048576 || str romaji name
  <table>
|-
    <tr>
|5 ||32 || not used || || 21 || 2097152 || str kanji name
    <td>'''Bit'''</td>
|- style="background-color: #eee;"
    <td align="right">'''Dec'''</td>
|6 ||64 || not used || || 22 || 4194304 || str english name
    <td>'''Data Field'''</td>
|-
    </tr>
|7 ||128 || not used || || 23 || 8388608 || str other name
    <tr>
|- style="background-color: #eee;"
    <td>7</td>
|8 ||256 || str epno || || 24 || 16777216 || str short name list
    <td align="right">128</td>
|-
    <td>int8 size</td>
|9 ||512 || str ep name || || 25 || 33554432 || str synonym list
    </tr>
|- style="background-color: #eee;"
    <tr bgcolor="#eeeeee">
|10 ||1024 || str ep romaji name || || 26 || 67108864 || str category list
    <td>6</td>
|-
    <td align="right">64</td>
|11 ||2048 || str ep kanji name || || 27 || 134217728 || str related aid list
    <td>str ed2k</td>
|- style="background-color: #eee;"
    </tr>
|12 ||4096 || not used || || 28 || 268435456 || str producer name list
    <tr>
|-
    <td>5</td>
|13 ||8192 || not used || || 29 || 536870912 || str producer id list
    <td align="right">32</td>
|- style="background-color: #eee;"
    <td>str md5</td>
|14 ||16384 || not used || || 30 || 1073741824 || not used
    </tr>
|-
    <tr bgcolor="#eeeeee">
|15 ||32768 || not used || || 31 || -2147483648 || not used
    <td>4</td>
|}
    <td align="right">16</td>
'''Examples:''' (html escaped code intended)
    <td>str sha1</td>
<pre>
    </tr>
> FILE fid=15201&s=xxxxx
    <tr>
< 220 FILE
    <td>3</td>
15201|74|445|41|1|242772540|a53c401ed95eaa502ba85acde773040c|Ai yori Aoshi - 1 - Relation - [Zhentarim DivX].ogm
    <td align="right">8</td>
    <td>str crc32</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>2</td>
    <td align="right">4</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>1</td>
    <td align="right">2</td>
    <td>video colour depth</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>0</td>
    <td align="right">1</td>
    <td>reserved</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td>'''Bit'''</td>
    <td align="right">'''Dec'''</td>
    <td>'''Data Field'''</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>str quality</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>str source</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>str audio codec list</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>int4 audio bitrate list</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>str video codec</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>int4 video bitrate</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>str video resolution</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td>str file type (extension)</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td>'''Bit'''</td>
    <td align="right">'''Dec'''</td>
    <td>'''Data Field'''</td>
    </tr>
    <tr>
    <td>7</td>
    <td align="right">128</td>
    <td>str dub language</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>6</td>
    <td align="right">64</td>
    <td>str sub language</td>
    </tr>
    <tr>
    <td>5</td>
    <td align="right">32</td>
    <td>int4 length in seconds</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>4</td>
    <td align="right">16</td>
    <td>str description</td>
    </tr>
    <tr>
    <td>3</td>
    <td align="right">8</td>
    <td>int4 aired date</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>2</td>
    <td align="right">4</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>1</td>
    <td align="right">2</td>
    <td>unused</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>0</td>
    <td align="right">1</td>
    <td>str anidb file name</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td>'''Bit'''</td>
    <td align="right">'''Dec'''</td>
    <td>'''Data Field'''</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>int4 mylist state</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>int4 mylist filestate</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>int4 mylist viewed</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>int4 mylist viewdate</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>str mylist storage</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>str mylist source</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>str mylist other</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td>unused</td>
    </tr>
  </table>
  </td>
</tr>
</table>


> FILE fid=15201&fcode=33554432&acode=1049346
<table border="0" cellpadding="0" cellspacing="2">
< 220 FILE
<tr><td colspan="4" align="center">'''amask:'''</td></tr>
15201|ogm|zx|01|Relation|Ai yori Aoshi
<tr>
  <td align="center">'''Byte 1'''</td>
  <td align="center">'''Byte 2'''</td>
  <td align="center">'''Byte 3'''</td>
  <td align="center">'''Byte 4'''</td>
</tr>
<tr>
  <td>
  <table>
    <tr>
    <td>'''Bit'''</td>
    <td align="right">'''Dec'''</td>
    <td>'''Data Field'''</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>int4 anime total episodes</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>int4 highest episode number</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>str year</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>str type</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>str related aid list</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>str related aid type</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>str category list</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td>reserved</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td>'''Bit'''</td>
    <td align="right">'''Dec'''</td>
    <td>'''Data Field'''</td>
    </tr>
    <tr>
    <td>7</td>
    <td align="right">128</td>
    <td>str romaji name</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>6</td>
    <td align="right">64</td>
    <td>str kanji name</td>
    </tr>
    <tr>
    <td>5</td>
    <td align="right">32</td>
    <td>str english name</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>4</td>
    <td align="right">16</td>
    <td>str other name</td>
    </tr>
    <tr>
    <td>3</td>
    <td align="right">8</td>
    <td>str short name list</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>2</td>
    <td align="right">4</td>
    <td>str synonym list</td>
    </tr>
    <tr>
    <td>1</td>
    <td align="right">2</td>
    <td><i>retired</i></td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>0</td>
    <td align="right">1</td>
    <td><i>retired</i></td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td>'''Bit'''</td>
    <td align="right">'''Dec'''</td>
    <td>'''Data Field'''</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>7</td>
    <td align="right">128</td>
    <td>str epno</td>
    </tr>
    <tr>
    <td>6</td>
    <td align="right">64</td>
    <td>str ep name</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>5</td>
    <td align="right">32</td>
    <td>str ep romaji name</td>
    </tr>
    <tr>
    <td>4</td>
    <td align="right">16</td>
    <td>str ep kanji name</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>3</td>
    <td align="right">8</td>
    <td>int4 episode rating</td>
    </tr>
    <tr>
    <td>2</td>
    <td align="right">4</td>
    <td>int4 episode vote count</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>1</td>
    <td align="right">2</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>0</td>
    <td align="right">1</td>
    <td>unused</td>
    </tr>
  </table>
  </td>
  <td>
  <table>
    <tr>
    <td>'''Bit'''</td>
    <td align="right">'''Dec'''</td>
    <td>'''Data Field'''</td>
    </tr>
    <tr>
    <td>7</td>
    <td align="right">128</td>
    <td>str group name</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>6</td>
    <td align="right">64</td>
    <td>str group short name</td>
    </tr>
    <tr>
    <td>5</td>
    <td align="right">32</td>
    <td>unused</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>4</td>
    <td align="right">16</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>3</td>
    <td align="right">8</td>
    <td>unused</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>2</td>
    <td align="right">4</td>
    <td>unused</td>
    </tr>
    <tr>
    <td>1</td>
    <td align="right">2</td>
    <td>unused</td>
    </tr>
    <tr bgcolor="#eeeeee">
    <td>0</td>
    <td align="right">1</td>
    <td>int4 date aid record updated</td>
    </tr>
  </table>
  </td>
</tr>
</table>


> FILE aname=narutaru&gname=triad&amp;amp;aone&epno=2&s=xxxxx
'''Examples:''' (html escaped code intended)
< t001 220 FILE
  > FILE size=177747474&ed2k=70cd93fd3981cc80a8ea6a646ff805c9&fmask=7FF8FEF8&amask=C000F0C0&s=xxxxx
15459|782|8772|380|1|171298816|2c8a3b53d94d8579b9b81941c549e108|Narutaru - 02 - Catastrophe During the Daytime - [Triad & AonE].avi
  < 220 FILE
</pre>
  312498|4688|69260|4243|0||0|1|177747474|70cd93fd3981cc80a8ea6a646ff805c9|b2a7c7d591333e20495de3571b235c28|7af9b962c17ff729baeee67533e5219526cd5095|a200fe73|high|DTV|Vorbis (Ogg Vorbis)|104|H264/AVC|800|704x400|japanese|english'english'english|1560||1175472000|26|26|01|The Wings to the Sky|Sora he no Tsubasa|????|#nanoha-DamagedGoodz|Nanoha-DGz


----
----
Line 750: Line 1,673:
'''Command String:'''<br>
'''Command String:'''<br>
by gid
by gid
* GROUP gid={int4 gid}
* GROUP gid={int gid}
by name/shortname
by name/shortname
* GROUP gname={str group name}
* GROUP gname={str group name}
Line 756: Line 1,679:
'''Possible Replies:'''
'''Possible Replies:'''
* 250 GROUP
* 250 GROUP
: {int4 gid}|{int4 rating}|{int4 votes}|{int4 acount}|{int fcount}|{str name}|{str short}|{str irc channel}|{str irc server}|{str url}
: {int gid}|{int4 rating}|{int votes}|{int4 acount}|{int fcount}|{str name}|{str short}|{str irc channel}|{str irc server}|{str url}|{str picname}|{int4 foundeddate}|{int4 disbandeddate}|{int2 dateflags}|{int4 lastreleasedate}|{int4 lastactivitydate}|{list grouprelations}
* 350 NO SUCH GROUP
* 350 NO SUCH GROUP


'''Examples:'''
'''Info:'''
  > GROUP gid=1&s=xxxxx
* Requires login
  < 250 GROUP
* ''gname'' is an exact match of either a group name or short name
  41|851|665|109|1004|Zhentarim DivX|zx|#zhentarim|irc.deltaanime.net|http://www.zhentarim.net/
* As either name and short names are unique if there is a result from GROUP request by name that will be the only match
* ''dateflags'' values:
** bit0 set == Foundeddate, Unknown Day
** bit1 set == Foundeddate, Unknown Month, Day
** bit2 set == Disbandeddate, Unknown Day
** bit3 set == Disbandeddate, Unknown Month, Day
** bit5 set == Foundeddate, Unknown Year
** bit6 set == Disbandeddate, Unknown Year
* ''releasedate'' and ''activitydate'' are distinct.  ''releasedate'' is the date a file was actually released by the group, where ''activitydate'' is the date of a file being added to AniDB. As such, lastrelease may very well be much older than lastactivity.
* ''groupreleations'' is a list of apostrophe-separated pairs, where each pair consists of {int4 othergroupid},{int2 relationtype}
** relationtype:
*** 1 => "Participant in"
*** 2 => "Parent of"
*** 4 => "Merged from"
*** 5 => "Now known as"
*** 6 => "Other"


   > GROUP gname=a-l&s=xxxxx
'''Example:'''
   > GROUP gid=7091&s=bunny
   < 250 GROUP
   < 250 GROUP
   566|840|453|53|534|Anime-Legion|A-L|#anime-legion|irc.irchighway.net|http://www.anime-legion.net
   7091|832|1445|43|566|Frostii|Frostii|#frostii|irc.rizon.net|<nowiki>http://frostii.com</nowiki>|15844.jpg|1228089600|0|1|1301875200|1304222640|7255,1'3097,4'748,4'8106,1'8159,2'8402,1'8696,1'9022,1


----
----
=== PRODUCER: Retrieve Producer Data ===
 
'''Command String:'''<br>
=== GROUPSTATUS: Get Completed Episode ===
by id
Returns a list of group names and ranges of episodes released by the group for a given anime.
* PRODUCER pid={int4 producer id}
 
by name
'''Command String:'''
* PRODUCER pname={str producer name/short name/other name}
* GROUPSTATUS aid={int animeid}[&state={int completion_state}]


'''Possible Replies:'''
'''Possible Replies:'''
* 245 PRODUCER
* 225 GROUPSTATUS
: {int4 id}|{str name}|{str short name}|{str other name}|{str type}|{str picture name}|{str home page url}
: {int group id}|{str group name}|{int completion state}|{int last episode number}|{int rating}|{int votes}|{str episode range}\n
* 345 NO SUCH PRODUCER
: {int group id}|{str group name}|{int completion state}|{int last episode number}|{int rating}|{int votes}|{str episode range}\n
: ... (repeated)
 
* 325 NO SUCH GROUPS FOUND
* 330 NO SUCH ANIME
 
'''Info:'''
* The seven fields will be repeated as necessary, one for each group, separated by a new line character
* Groups will be filtered by the languages selected in the user's profile
* If ''state'' is not supplied, groups with a completion state of <i>'ongoing'</i>, <i>'finished'</i>, or <i>'complete'</i> are returned
* Groups are returned in order of descending episode count
* If there are more groups to return than can be stored in a UDP packet, additional groups will be silently discarded
* ''state'' values:
#ongoing
#stalled
#complete
#dropped
#finished
#specials only
 
'''Example:'''
'''Example:'''
   > PRODUCER pid=1
   > GROUP GROUPSTATUS aid=8692&s=vLl1N
   < 245 PRODUCER
   < 225 GROUPSTATUS
   1|GAINAX||ガイナックス|Company|1088.gif|http://www.gainax.co.jp/
   7407|Coalgirls|3|25|839|12|1-25
  9863|Hadena Subs|3|25|374|1|1-25
  11951|ChaosBlades|3|25|0|0|1-25
  [truncated]
 
=== UPDATED: Get List of Updated Anime IDs ===
Returns a list of AniDB anime ids of anime that have been updated in in a given time frame, ordered by descending age (oldest to newest change).


== Mylist Commands ==
'''Command String:'''
=== MYLIST: Retrieve Mylist Data ===
* UPDATED entity=1&[age={int4 id}|time={int4 date}]
 
'''Possible Replies:'''
* 243 UPDATED
{int entity}|{int total count}|{int last update date}|{list aid}
 
* 343 NO UPDATES
 
'''Info:'''
* ''entity'' is always 1
* Either ''age'' OR ''time'' can be specified, but not both
* ''age'' is specified in days.
** eg: age=30 requests a list of aid values of anime that have changed in the past 30 days
* ''time'' is specified in unix time.
** eg: time=1264982400 requests a list of aid values of anime that have changed since 2010-02-01
* A maximum of 200 values will be returned
* ''count'' specifies the total number of items found for the given time period.  In short, if this value is great than 200, you have not retrieved all applicable ids.
* ''last update date'' will contain the AniDB update time of the ''last'' aid to appear on the list
* A given list value will appear only once.  If there have been multiple changes to an entity, its age will reflect the most recent change.
 
'''An anime will be considered updated if:'''
* A change is made to the anime record itself
* An ''main'' or ''official'' anime title is added, edited, or deleted (not ''short'' or ''synonym'')
* An episode for the anime is added, or deleted (but NOT edited!)
* An episode title is added, edited, or deleted
* An anime relation is added, or deleted
 
== MyList Commands ==
=== MYLIST: Retrieve MyList Data ===
'''Command String:'''<br>
'''Command String:'''<br>
by lid: (mylist id)
by lid: (mylist id)
Line 802: Line 1,794:
'''Possible Replies:'''
'''Possible Replies:'''
* 221 MYLIST
* 221 MYLIST
: {int4 lid}|{int4 fid}|{int4 eid}|{int4 aid}|{int4 gid}|{int4 date}|{int2 state}|{int4 viewdate}|{str storage}|{str source}|{str other}
: {int4 lid}|{int4 fid}|{int4 eid}|{int4 aid}|{int4 gid}|{int4 date}|{int2 state}|{int4 viewdate}|{str storage}|{str source}|{str other}|{int2 filestate}
* 312 MULTIPLE MYLIST ENTRIES
* 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}
: {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}
Line 808: Line 1,800:


'''Info:'''
'''Info:'''
* The state field provides information about the location and sharing state of a file in mylist.
* 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).
* 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"
* eps is a list of episodes, e.g. "1-12,14-16,T1"


'''States:'''
'''States:'''
   0 - unknown - state is unknown or the user doesn't want to provide this information
   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)
   1 - internal storage - the file is stored on hdd (but is not shared)
   2 - on cd - the file is stored on cd
   2 - external storage - the file is stored on cd/dvd/...
   3 - deleted - the file has been deleted or is not available for other reasons (i.e. reencoded)
   3 - deleted - the file has been deleted or is not available for other reasons (i.e. reencoded)
  4 - remote storage - the file is stored on NAS/cloud/...
'''Filestates:''' (for normal files, i.e. not generic)
  0  => normal/original
  1  => corrupted version/invalid crc
  2  => self edited
  10  => self ripped
  11  => on dvd
  12  => on vhs
  13  => on tv
  14  => in theaters
  15  => streamed
  100 => other


'''Example:'''
'''Example:'''
Line 825: Line 1,830:
----
----


=== MYLISTADD: Add file to mylist ===
=== MYLISTADD: Add file to MyList ===
'''Command String:'''<br>
The command string for MYLISTADD is made of up two blocks: a 'fileinfo' block, which limits the command to a specific file, or an 'animeinfo'/'groupinfo'/'episodeinfo' block, which can be used to specify a range of files, including generics.  Additionally, a number of optional parameters can be included with either set.
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}]
'''Adding a single file to the MyList with the 'fileinfo' block'''
by fid:
 
* MYLISTADD fid={int4 fid}[&state={int2 state}&viewed={boolean viewed}&source={str source}&storage={str storage}&other={str other}][&edit=1]
* MYLISTADD fid={int4 fid}
by size+ed2k hash:
'''or'''
* MYLISTADD size={int4 size}&ed2k={str ed2khash}[&state={int2 state}&viewed={boolean viewed}&source={str source}&storage={str storage}&other={str other}][&edit=1]
* MYLISTADD size={int4 size}&ed2k={str ed2khash}
by anime + group + epno
'''or'''
* MYLISTADD aname={str anime name}[&gname={str group name}&epno={int4 episode number}][&state={int2 state}&viewed={boolean viewed}&source={str source}&amp;storage={str storage}&other={str other}][&edit=1]
* MYLISTADD lid={int4 lid}&edit=1  (valid for edit only)
* 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}][...]
'''Adding one or more files to the MyList with the 'animeinfo'/'groupinfo'/'episodeinfo' block'''
* MYLISTADD aid={int4 anime id}[&gid={int4 group id}&epno={int4 episode number}][...]
 
Here, you have a number of options, depending on what data you have available.  In brief, 'animeinfo' represents a choice between anime id and anime name.  'groupinfo' represents a choice between group id, group name, and generic=1.  'episodeinfo' represents a range of one or more episodes.
 
* MYLISTADD aid={int4 aid}&gid={int gid}&epno={int4 episode number}
'''or'''
* MYLISTADD aid={int4 aid}&gname={str group_name}&epno={int4 episode number}
'''or'''
* MYLISTADD aid={int4 aid}&generic=1&epno={int4 episode number}
'''or'''
* MYLISTADD aname={str anime_name}&gid={int gid}&epno={int4 episode number}
'''or'''
* MYLISTADD aname={str anime_name}&gname={str group_name}&epno={int4 episode number}
'''or'''
* MYLISTADD aname={str anime_name}&generic=1&epno={int4 episode number}
 
Each command listed can have, in addition, a number of optional components to provide further MyList details. Append these as desired.
 
* &state={int2 state}
* &viewed={boolean viewed}
* &viewdate={int4 viewdate}
* &source={str source}
* &storage={str storage}
* &other={str other}
 
Finally, edit=1 can be included to edit a MyList entry instead of creating a new one.  When editing, optional values that are not supplied retain their original value. That is, they are ''not'' replaced with default or empty values. Only values supplied are updated.


'''Possible Replies:'''
'''Possible Replies:'''
Line 843: Line 1,872:
* 330 NO SUCH ANIME
* 330 NO SUCH ANIME
* 350 NO SUCH GROUP
* 350 NO SUCH GROUP
when edit=0
when edit=0 and adding by fid, size/ed2k
* 210 MYLIST ENTRY ADDED
: {int4 mylist id of new entry}
when edit=0 and adding by aname, aid
* 210 MYLIST ENTRY ADDED
* 210 MYLIST ENTRY ADDED
: {int4 number of entries added}
: {int4 number of entries added}
* 310 FILE ALREADY IN MYLIST
* 310 FILE ALREADY IN MYLIST
: {int4 lid}|{int4 fid}|{int4 eid}|{int4 aid}|{int4 gid}|{int4 date}|{int2 state}|{int4 viewdate}|{str storage}|{str source}|{str other}|{int2 filestate}
* 322 MULTIPLE FILES FOUND
* 322 MULTIPLE FILES FOUND
: {int4 fid 1}|{int4 fid 2}|...|{int4 fid n}
: {int4 fid 1}|{int4 fid 2}|...|{int4 fid n}
Line 856: Line 1,889:


'''Info:'''
'''Info:'''
* All data except lid/fid/size+hash is optional.
* All data except lid/fid/size+hash/generic is optional.
* Viewed should be 0 for unwatched files and 1 for watched files.
* 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 &lt;br /&gt;
* If viewdate is not specified, the current time will be used. The field will be disregarded if viewed=0.
* If edit is 1 then an existing entry, if found, will be updated with the given values.
* Other is the only field which may contain newlines, but they have to be stored as &lt;br /&gt;
* For state values refer to: '''MYLIST'''
* 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.
* If you want to change an existing entry and already know its 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)
* 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
* group is optional only when edit=1, meaning you can't add every file for an anime
{{eyecatch|NOTE|This command does not update the the cached mylist counts seen in [[Myplace]].}}
* If the file already exists (response code 310), the ''current'' record will be returned, in the same format as the MYLIST response.
 
----
----


=== MYLISTDEL: Remove file from mylist ===
=== MYLISTDEL: Remove file from MyList ===
'''Command String:'''<br>
'''Command String:'''<br>
by lid: (mylist id)
by lid: (mylist id)
Line 874: Line 1,906:
by fid:
by fid:
* MYLISTDEL fid={int4 fid}
* MYLISTDEL fid={int4 fid}
by size+ed2k hash:
* MYLISTDEL size={int4 size}&ed2k={str ed2k hash}
by anime + group + epno
by anime + group + epno
* MYLISTDEL aname={str anime name}[&gname={str group name}&epno={int4 episode number}]
* MYLISTDEL aname={str anime name}[&gname={str group name}&epno={int4 episode number}]
Line 889: Line 1,923:


----
----
 
=== MYLISTSTATS : Retrieve MyList stats ===
=== MYLISTSTATS : Retrieve mylist stats ===
'''Command String:'''
'''Command String:'''
* MYLISTSTATS
* MYLISTSTATS
'''Possible Replies:'''
'''Possible Replies:'''
* 222 MYLIST STATS
* 222 MYLIST STATS
{animes}|{eps}|{files}|{size of files}|{added animes}|{added eps}|{added files}|{added groups}|{leech %}|{glory %}|{viewed % of db}|{mylist % of db}|{viewed % of mylist}|{number of viewed eps}|{votes}|{reviews}
{animes}|{eps}|{files}|{size of files}|{added animes}|{added eps}|{added files}|{added groups}|{leech %}|{glory %}|{viewed % of db}|{mylist % of db}|{viewed % of mylist}|{number of viewed eps}|{votes}|{reviews}|{viewed length in minutes}


'''Info:'''
'''Info:'''
Line 906: Line 1,939:
by id
by id
* VOTE type={int2 type}&id={int4 id}[&value={int4 vote value}&epno={int4 episode number}]
* VOTE type={int2 type}&id={int4 id}[&value={int4 vote value}&epno={int4 episode number}]
* VOTE type={int2 type}&id={int4 id}[&value={int4 vote value}&epno={str episode number}]
by name
by name
* VOTE type={int2 type}&name={string name}[&value={int4 vote value}&epno={int4 episode number}]
* VOTE type={int2 type}&name={string name}[&value={int4 vote value}&epno={int4 episode number}]
* VOTE type={int2 type}&name={string name}[&value={int4 vote value}&epno={str episode number}]


'''Possible Replies:'''
'''Possible Replies:'''
* 260 VOTED
* 260 VOTED
: {str aname/ename/gname}
: {str entity name}|{vote value}|{vote type}|{entity id}
* 261 VOTE FOUND
* 261 VOTE FOUND
: {str aname/ename/gname}|{vote value}
: {str entity name}|{vote value}|{vote type}|{entity id}
* 262 VOTE UPDATED
* 262 VOTE UPDATED
: {str aname/ename/gname}|{old vote value}
: {str entity name}|{old vote value}|{vote type}|{entity id}
* 263 VOTE REVOKED
* 263 VOTE REVOKED
: {str aname/ename/gname}|{revoked vote value}
: {str entity name}|{revoked vote value}|{vote type}|{entity id}
* 360 NO SUCH VOTE
* 360 NO SUCH VOTE
: {str entity name}|0|{vote type}|{entity id}
* 361 INVALID VOTE TYPE
* 361 INVALID VOTE TYPE
* 362 INVALID VOTE VALUE
* 362 INVALID VOTE VALUE
* 363 PERMVOTE NOT ALLOWED
* 363 PERMVOTE NOT ALLOWED
: {str aname}
: {str aname}|{vote value}|{type}|{entity id}
* 364 ALREADY PERMVOTED
* 364 ALREADY PERMVOTED
: {str aname/ename/gname}
: {str entity name}|{existing vote value}|{vote type}|{entity id}
 
'''Example:'''
  VOTE type=1&id=5101&value=950
  260 VOTED
  Clannad|950|1|5101
 
  VOTE type=1&id=5101&value=950&epno=S2
  260 VOTED
  Another World: Tomoyo Arc|950|1|91981
 
  VOTE type=6&id=91981&value=950
  260 VOTED
  Another World: Tomoyo Arc|950|1|91981


'''Info:'''
'''Info:'''
* type: 1=anime, 2=anime tmpvote, 3=group
* Type: 1=anime, 2=anime tmpvote, 3=group, 6=episode
* for episode voting add epno on type=1
* Entity: anime, episode, or group
* value: negative number means revoke, 0 means retrieve (default), 100-1000 are valid vote values, rest is illegal
* For episode voting add epno on type=1, or specify type=6 if eid is known
* votes will be updated automatically (no questions asked)
* Value: negative number means revoke, 0 means retrieve (default), 100-1000 are valid vote values, rest is illegal
* tmpvoting when there exist a perm vote is not possible
* Votes will be updated automatically (no questions asked)
* Tmpvoting when there exist a perm vote is not possible


----
----
=== RANDOM: Get a random anime ===
=== RANDOM: Get a random anime ===
'''Command String:'''
'''Command String:'''
Line 945: Line 1,996:


== Misc Commands ==
== Misc Commands ==
=== MYLISTEXPORT: Schedule a MyList Export ===
Queues a {{AniDBLink|export|MyList Export}} by the AniDB Servers.  As with a manual export request, exports are only done during periods when server load is low. As a result, exports may take up to 24 hours. The client submitting the request will receive an AniDB message when the export is ready to be collected.
Only one export can be in the queue at a time.
'''Command String:'''
* MYLISTEXPORT [template={str template_name}|cancel=1]
'''Possible Replies:'''
* 217 EXPORT QUEUED
* 218 EXPORT CANCELLED
* 317 EXPORT NO SUCH TEMPLATE
* 318 EXPORT ALREADY IN QUEUE
* 319 EXPORT NO EXPORT QUEUED OR IS PROCESSING
'''Info:'''
* ''template_name'' must match an available export template on the {{AniDBLink|export|MyList Export}} page.
* ''cancel'' will cancel any pending export request, queued either through UDP or the web server.
* Clients can subscribe the message notifications if they wish to be notified when an export is complete.
----
=== PING: Ping Command ===
=== PING: Ping Command ===
'''Command String:'''
'''Command String:'''
Line 957: Line 2,030:
* 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])
* The option <tt>nat=1</tt> provides an easy way to determine if the router has changed the outgoing port. ({{t|587}})


----
----
Line 973: Line 2,046:


----
----
=== UPTIME: Retrieve Server Uptime ===
=== UPTIME: Retrieve Server Uptime ===
'''Command String:'''
'''Command String:'''
Line 986: Line 2,058:


----
----
=== ENCODING: Change Encoding for Session ===
=== ENCODING: Change Encoding for Session ===
Sets preferred [http://en.wikipedia.org/wiki/Character_encoding encoding] per session. The preferred way to do this is to use the '''enc''' argument for AUTH. This command is mostly for testing.
Sets preferred [[Wikipedia:Character encoding|encoding]] per session. The preferred way to do this is to use the '''enc''' argument for AUTH. This command is mostly for testing.


'''Command String:'''
'''Command String:'''
Line 1,004: Line 2,075:


----
----
=== SENDMSG: Send Message ===
=== SENDMSG: Send Message ===
'''Command String:'''
'''Command String:'''
Line 1,015: Line 2,087:
'''Note:'''
'''Note:'''
* This command allows you to send an AniDB message.
* This command allows you to send an AniDB message.
{{eyecatch|IMPORTANT:|
{{eyecatch|Important|
title must not be longer than 50 chars.
title must not be longer than 50 chars.<br>
body must not be longer than 900 chars.
body must not be longer than 900 chars.
}}
}}


----
----
=== USER: Retrieve User UID ===
=== USER: Retrieve User UID ===
'''Command String:'''
'''Command String:'''
* USER user={str user name}
* USER [user={str user name}|uid={int user id}]


'''Possible Replies:'''
'''Possible Replies:'''
* 394 NO SUCH USER
* 394 NO SUCH USER
* 295 USER
* 295 USER
: {int4 uid}
: {int4 uid}|{str username}
'''Info:'''
* The client should the check length (3-10) and case (lower) of ''user'' before sending.


----
----


=== STATS [<span style="color:red">disabled</span>] ===
=== STATS [{{colour|red|disabled}}] ===
'''Command String:'''
'''Command String:'''
* STATS
* STATS
Line 1,044: Line 2,113:


----
----
 
=== TOP [{{colour|red|disabled}}] ===
=== TOP [<span style="color:red">disabled</span>] ===
'''Command String:'''
'''Command String:'''
* TOP
* TOP
Line 1,074: Line 2,142:
*6xx INTERNAL SERVER ERROR - {str errormessage}
*6xx INTERNAL SERVER ERROR - {str errormessage}


Such errors should be reported back to [[User:Epoximator|Epoximator]].
Such errors should be reported back to [[User:Ommina|Ommina]].
(xx is a number between 00 and 99)
(xx is a number between 00 and 99)


Line 1,081: Line 2,149:


== Return Codes ==
== Return Codes ==
Note: The names below do _not_ necessarily reflect the actual code strings returned by the server.  
{{eyecatch|Note|While the names below '''are''' the actual code strings returned by the server, clients are nonetheless encouraged to work with the numeric codes instead. }}
<pre>
<pre>
// POSITIVE 2XX
LOGIN_ACCEPTED                           = 200
 
LOGIN_ACCEPTED_NEW_VERSION              = 201
LOGIN_ACCEPTED =200, //a
LOGGED_OUT                               = 203
LOGIN_ACCEPTED_NEW_VER =201, //a
RESOURCE                                 = 205
LOGGED_OUT =203, //a
STATS                                   = 206
RESOURCE =205, //d
TOP                                     = 207
STATS =206, //b
UPTIME                                   = 208
TOP =207, //b
ENCRYPTION_ENABLED                       = 209
UPTIME =208, //b
MYLIST_ENTRY_ADDED                       = 210
ENCRYPTION_ENABLED =209, //c
MYLIST_ENTRY_DELETED                     = 211
 
ADDED_FILE                               = 214
MYLIST_ENTRY_ADDED =210, //a
ADDED_STREAM                             = 215
MYLIST_ENTRY_DELETED =211, //a
EXPORT_QUEUED                            = 217
 
EXPORT_CANCELLED                        = 218
ADDED_FILE =214, //e
ENCODING_CHANGED                         = 219
ADDED_STREAM =215, //e
FILE                                    = 220
 
MYLIST                                  = 221
ENCODING_CHANGED =219, //c
MYLIST_STATS                            = 222
WISHLIST                                = 223
NOTIFICATION                            = 224
GROUP_STATUS                            = 225
WISHLIST_ENTRY_ADDED                    = 226
WISHLIST_ENTRY_DELETED                  = 227
WISHLIST_ENTRY_UPDATED                  = 228
MULTIPLE_WISHLIST                        = 229
ANIME                                    = 230
ANIME_BEST_MATCH                        = 231
RANDOM_ANIME                            = 232
ANIME_DESCRIPTION                        = 233
REVIEW                                  = 234
CHARACTER                                = 235
SONG                                    = 236
ANIMETAG                                = 237
CHARACTERTAG                            = 238
EPISODE                                  = 240
UPDATED                                  = 243
TITLE                                    = 244
CREATOR                                  = 245
NOTIFICATION_ENTRY_ADDED                = 246
NOTIFICATION_ENTRY_DELETED              = 247
NOTIFICATION_ENTRY_UPDATE                = 248
MULTIPLE_NOTIFICATION                    = 249
GROUP                                    = 250
CATEGORY                                = 251
BUDDY_LIST                              = 253
BUDDY_STATE                              = 254
BUDDY_ADDED                              = 255
BUDDY_DELETED                            = 256
BUDDY_ACCEPTED                          = 257
BUDDY_DENIED                            = 258
VOTED                                    = 260
VOTE_FOUND                              = 261
VOTE_UPDATED                            = 262
VOTE_REVOKED                            = 263
HOT_ANIME                                = 265
RANDOM_RECOMMENDATION                    = 266
RANDOM_SIMILAR                          = 267
NOTIFICATION_ENABLED                    = 270
NOTIFYACK_SUCCESSFUL_MESSAGE            = 281
NOTIFYACK_SUCCESSFUL_NOTIFICATION        = 282
NOTIFICATION_STATE                      = 290
NOTIFYLIST                              = 291
NOTIFYGET_MESSAGE                        = 292
NOTIFYGET_NOTIFY                        = 293
SENDMESSAGE_SUCCESSFUL                  = 294
USER_ID                                  = 295
CALENDAR                                = 297


FILE =220, //a
PONG                                    = 300
MYLIST =221, //a
AUTHPONG                                = 301
MYLIST_STATS =222, //b
NO_SUCH_RESOURCE                        = 305
API_PASSWORD_NOT_DEFINED                = 309
FILE_ALREADY_IN_MYLIST                  = 310
MYLIST_ENTRY_EDITED                      = 311
MULTIPLE_MYLIST_ENTRIES                  = 312
WATCHED                                  = 313
SIZE_HASH_EXISTS                        = 314
INVALID_DATA                            = 315
STREAMNOID_USED                          = 316
EXPORT_NO_SUCH_TEMPLATE                  = 317
EXPORT_ALREADY_IN_QUEUE                  = 318
EXPORT_NO_EXPORT_QUEUED_OR_IS_PROCESSING = 319
NO_SUCH_FILE                            = 320
NO_SUCH_ENTRY                            = 321
MULTIPLE_FILES_FOUND                    = 322
NO_SUCH_WISHLIST                        = 323
NO_SUCH_NOTIFICATION                    = 324
NO_GROUPS_FOUND                          = 325
NO_SUCH_ANIME                            = 330
NO_SUCH_DESCRIPTION                      = 333
NO_SUCH_REVIEW                          = 334
NO_SUCH_CHARACTER                        = 335
NO_SUCH_SONG                            = 336
NO_SUCH_ANIMETAG                        = 337
NO_SUCH_CHARACTERTAG                    = 338
NO_SUCH_EPISODE                          = 340
NO_SUCH_UPDATES                          = 343
NO_SUCH_TITLES                          = 344
NO_SUCH_CREATOR                          = 345
NO_SUCH_GROUP                            = 350
NO_SUCH_CATEGORY                        = 351
BUDDY_ALREADY_ADDED                      = 355
NO_SUCH_BUDDY                            = 356
BUDDY_ALREADY_ACCEPTED                  = 357
BUDDY_ALREADY_DENIED                    = 358
NO_SUCH_VOTE                            = 360
INVALID_VOTE_TYPE                        = 361
INVALID_VOTE_VALUE                      = 362
PERMVOTE_NOT_ALLOWED                    = 363
ALREADY_PERMVOTED                        = 364
HOT_ANIME_EMPTY                          = 365
RANDOM_RECOMMENDATION_EMPTY              = 366
RANDOM_SIMILAR_EMPTY                    = 367
NOTIFICATION_DISABLED                    = 370
NO_SUCH_ENTRY_MESSAGE                    = 381
NO_SUCH_ENTRY_NOTIFICATION              = 382
NO_SUCH_MESSAGE                          = 392
NO_SUCH_NOTIFY                          = 393
NO_SUCH_USER                            = 394
CALENDAR_EMPTY                          = 397
NO_CHANGES                              = 399


ANIME =230, //b
NOT_LOGGED_IN                            = 403
ANIME_BEST_MATCH =231, //b
NO_SUCH_MYLIST_FILE                      = 410
RANDOMANIME =232, //b
NO_SUCH_MYLIST_ENTRY                    = 411
MYLIST_UNAVAILABLE                      = 412


EPISODE =240, //b
LOGIN_FAILED                            = 500
PRODUCER =245, //b
LOGIN_FIRST                              = 501
GROUP =250, //b
ACCESS_DENIED                            = 502
CLIENT_VERSION_OUTDATED                  = 503
CLIENT_BANNED                            = 504
ILLEGAL_INPUT_OR_ACCESS_DENIED          = 505
INVALID_SESSION                          = 506
NO_SUCH_ENCRYPTION_TYPE                  = 509
ENCODING_NOT_SUPPORTED                  = 519
BANNED                                  = 555
UNKNOWN_COMMAND                          = 598


BUDDY_LIST =253, //c
INTERNAL_SERVER_ERROR                    = 600
BUDDY_STATE =254, //c
ANIDB_OUT_OF_SERVICE                    = 601
BUDDY_ADDED =255, //c
SERVER_BUSY                              = 602
BUDDY_DELETED =256, //c
NO_DATA                                  = 603
BUDDY_ACCEPTED =257, //c
TIMEOUT - DELAY AND RESUBMIT            = 604
BUDDY_DENIED =258, //c
API_VIOLATION                            = 666


VOTED =260, //b
PUSHACK_CONFIRMED                        = 701
VOTE_FOUND =261, //b
NO_SUCH_PACKET_PENDING                  = 702
VOTE_UPDATED =262, //b
VOTE_REVOKED =263, //b


NOTIFICATION_ENABLED =270, //a
VERSION                                 = 998</pre>
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
</pre>
 
== Changelog ==
<pre>
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
</pre>


[[Category:Development]]
[[Category:Development]]
[[Category:UDP]]
[[Category:UDP]]
[[Category:API]]
MediaWiki spam blocked by CleanTalk.
MediaWiki spam blocked by CleanTalk.