Web-cp 0.6 boasts an XML-RPC based API that can be used by external application to do various things.

Framework

Web-cp uses the XMLRPC functions/classes written by Keith Devens. On top of that is a thin layer that interfaces the hooks system with XML-RPC. In addition, system.multicall, system.cascadecall (custom to web-cp) and system.listMethods are also implemented.

Inner workings

The file web/rpc.php functions largely in the same way as web/index.php, but instead of accepting query strings and outputting HTML, it uses XML. Authentication is handled by sending either a username, domain and password, or username, domain, time (which is used as a salt) and a password hash. This is than verified against the database and a session key is returned. This session key (the webcp_tag) is valid for 5 minutes, which should be more than enough for simple calls. Remeber, the XML-RPC API is meant for automated batch processing, etc. After that, the user executes calls by sending this session key along.

Sending parameters

Three different ways of sending paramaters is supported
  1. Sending all data as XML via POST: this is how XML-RPC is supposed to work
  2. Sending all data as XML in the variable q, either via POST or GET: This is a backup in case your library can't POST XML directly. GET should not be used, except maybe for very small amounts of data
  3. Sending data via the query string. No XML is sent, but the data returned will be the same as the previous methods. The methodCall is specified in "method", the session key in "session" and any data in "data". An URI using this approach for logging in would look like this: /rpc.php?method=system.login&data[username]=username&data[domain]=domain.com&data[password]=password

Usage

Familiarity with XML-RPC and an appropriate library is assumed. You begin by calling the system.login method with a single paramater: a struct.

This struct can have two formats
  1. username and password in plaintext: this is only recommended over SSL or localhost
  2. username, time (in GMT, using the ISO8601 format!) and a hash. The hash is calculated like this: md5($password.$time)

You will either get back an error, or the session key (a 32 character base64 string, beginning with a +)

You can now make any available call, passing the session key as the first parameter and optionally any data in a struct as the second parameter. For a list of available methods, use system.listMethods.

Error codes

  • <=2999: means "nothing wrong", and so they should never be returned as an error code.
  • 3000-3099 means a non-fatal error. It's currently only used if your login has expired. Logging in again and using the new session key should fix this.
  • 3100-3999: these are not specifically defined and may be used by hooks as they please for non-fatal errors.
  • 4000-4098 means something went wrong. The problem is most likely on your side.
  • 4099: Permission Denied. This is returned if you're trying to do something the current user isn't supposed to/allowed to.
  • 4100-4999 means the method that was called has failed. More detail should be in the accompanying string. These are not specifically defined and may be used by hooks as they please for errors most likely attributable to the user.
  • 5000-5099 means that something is wrong with the server. 5000 is currently the only code and it means that the "ext" module isn't enabled.
  • 5100-5999: these are not specifically defined and may be used by hooks as they please for errors on their side.
  • 6000+: Not currently defined and should not be used for anything

Any error codes not in the X0XX format are method specific and could mean different things depending on which method was called.

system.multicall

You can call multiple methods in one request. See documentation on system.multicall on how to use this. If your first called method is system.login, no session key needs to be specified. If system.login is not part of the system.multicall, only the first method call needs to have a valid session key, you can leave the other blank or omit them entirely.

system.cascadecall

Works like system.multicall, except the output of one call is passed as input to the next. The chain will only be executed until an error occurs. This means that you may not get as many responses as requests. system.multicalls can be nested in system.cascadecalls and vice versa. If a system.multicall is nested inside a system.cascadecall, each call will receive the response from the parent call. This can can be used to create a reseller, domain and user at once, or even mutliple resellers/domains/users.

Notice: "unserialize() [<a href='function.unserialize'>function.unserialize</a>]: Error at offset 2353 of 2367 bytes" (...repeated 2 times)